<?php
/**
 * Catálogo de tipos/tamaños para rótulos de rollos.
 *
 * @package Logistica
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * CRUD de definiciones de ancho para rótulos de rollos.
 */
class Logistica_Rotulo_Rollos_Catalog {

	/**
	 * Tipos comunes de material en rollo.
	 *
	 * @return array<string, string>
	 */
	public static function tipo_options() {
		if ( class_exists( 'Logistica_Select_Catalog', false ) ) {
			$options = Logistica_Select_Catalog::get_options( 'rotulo_tipos' );
			if ( is_array( $options ) && ! empty( $options ) ) {
				return $options;
			}
		}

		return array(
			'ROLLO'  => __( 'Rollo', 'logistica' ),
			'FONDOS' => __( 'Fondos', 'logistica' ),
		);
	}

	/**
	 * Tamaños sugeridos para el select de rótulos.
	 *
	 * @return list<string>
	 */
	public static function tamano_options() {
		if ( class_exists( 'Logistica_Select_Catalog', false ) ) {
			$options = Logistica_Select_Catalog::get_options( 'rotulo_tamanos' );
			if ( is_array( $options ) && ! empty( $options ) ) {
				return array_values( $options );
			}
		}

		return array( '68 CM', '85 MM', '100 CM' );
	}

	/**
	 * @return array<int, array<string, mixed>>
	 */
	public static function get_all() {
		global $wpdb;

		$table = Logistica_Database::table( 'rotulo_rollos' );
		if ( ! $table ) {
			return array();
		}

		$rows = $wpdb->get_results(
			'SELECT * FROM ' . $table . ' WHERE ' . Logistica_Soft_Delete::sql_not_deleted( 'rotulo_rollos' ) . ' ORDER BY tipo ASC, tamano ASC, id ASC', // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			ARRAY_A
		);

		if ( ! is_array( $rows ) ) {
			return array();
		}

		return array_map( array( __CLASS__, 'hydrate_row' ), $rows );
	}

	/**
	 * @param array<string, mixed> $row Fila DB.
	 * @return array<string, mixed>
	 */
	public static function hydrate_row( $row ) {
		if ( ! is_array( $row ) ) {
			return array();
		}

		$tipo   = strtoupper( sanitize_text_field( (string) ( $row['tipo'] ?? '' ) ) );
		$tamano = sanitize_text_field( (string) ( $row['tamano'] ?? '' ) );

		return array(
			'id'            => (int) ( $row['id'] ?? 0 ),
			'tipo'          => $tipo,
			'tipo_label'    => self::tipo_options()[ $tipo ] ?? $tipo,
			'tamano'        => $tamano,
			'ancho_label'   => self::build_ancho_label( $tipo, $tamano ),
			'accent_color'  => Logistica_Rotulo_Rollos_Print::color_for_tamano( $tamano ),
			'observaciones' => (string) ( $row['observaciones'] ?? '' ),
			'updated_at'    => (string) ( $row['updated_at'] ?? '' ),
		);
	}

	/**
	 * Texto de búsqueda para filtros del listado.
	 *
	 * @param array<string, mixed> $row Fila hidratada.
	 * @return string
	 */
	public static function build_row_search_text( $row ) {
		if ( ! is_array( $row ) ) {
			return '';
		}

		$parts = array(
			(string) ( $row['tipo_label'] ?? '' ),
			(string) ( $row['tipo'] ?? '' ),
			(string) ( $row['tamano'] ?? '' ),
			(string) ( $row['ancho_label'] ?? '' ),
			(string) ( $row['observaciones'] ?? '' ),
		);

		$parts = array_filter(
			array_map(
				static function ( $part ) {
					return strtolower( trim( (string) $part ) );
				},
				$parts
			)
		);

		return implode( ' ', $parts );
	}

	/**
	 * Texto visible en la fila ANCHO del rótulo.
	 *
	 * @param string $tipo   Tipo (ROLLO, FONDOS…).
	 * @param string $tamano Tamaño (68 CM, 85 MM…).
	 * @return string
	 */
	public static function build_ancho_label( $tipo, $tamano ) {
		$tipo   = strtoupper( trim( (string) $tipo ) );
		$tamano = trim( (string) $tamano );

		if ( '' !== $tipo && '' !== $tamano ) {
			return $tipo . ' ' . $tamano;
		}

		return $tipo ?: $tamano;
	}

	/**
	 * @param array<string, mixed> $row Fila hidratada.
	 * @return array<string, mixed>|null
	 */
	public static function format_row_for_client( $row ) {
		if ( ! is_array( $row ) || empty( $row['id'] ) ) {
			return null;
		}

		return array(
			'id'            => (int) $row['id'],
			'tipo'          => (string) $row['tipo'],
			'tipo_label'    => (string) ( $row['tipo_label'] ?? $row['tipo'] ),
			'tamano'        => (string) $row['tamano'],
			'ancho_label'   => (string) ( $row['ancho_label'] ?? self::build_ancho_label( $row['tipo'], $row['tamano'] ) ),
			'accent_color'  => (string) ( $row['accent_color'] ?? Logistica_Rotulo_Rollos_Print::color_for_tamano( $row['tamano'] ?? '' ) ),
			'observaciones' => (string) ( $row['observaciones'] ?? '' ),
		);
	}

	/**
	 * @param int $id Row ID.
	 * @return array<string, mixed>|null
	 */
	public static function get_by_id( $id ) {
		global $wpdb;

		$id = (int) $id;
		if ( $id <= 0 ) {
			return null;
		}

		$table = Logistica_Database::table( 'rotulo_rollos' );
		$row   = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM {$table} WHERE id = %d LIMIT 1", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$id
			),
			ARRAY_A
		);

		return is_array( $row ) ? self::hydrate_row( $row ) : null;
	}

	/**
	 * @param array<string, mixed> $data Form payload.
	 * @return array<string, mixed>|\WP_Error
	 */
	public static function save_row( $data ) {
		global $wpdb;

		$table = Logistica_Database::table( 'rotulo_rollos' );
		if ( ! $table ) {
			return new WP_Error( 'missing_table', __( 'Tabla de rótulos de rollos no disponible.', 'logistica' ) );
		}

		$id            = absint( $data['id'] ?? 0 );
		$tipo          = strtoupper( sanitize_text_field( (string) ( $data['tipo'] ?? '' ) ) );
		$tamano        = sanitize_text_field( (string) ( $data['tamano'] ?? '' ) );
		$observaciones = sanitize_textarea_field( (string) ( $data['observaciones'] ?? '' ) );
		$now           = current_time( 'mysql' );

		if ( '' === $tipo ) {
			return new WP_Error( 'missing_type', __( 'El tipo es obligatorio.', 'logistica' ) );
		}

		if ( '' === $tamano ) {
			return new WP_Error( 'missing_size', __( 'El tamaño es obligatorio.', 'logistica' ) );
		}

		$payload = array(
			'tipo'          => $tipo,
			'tamano'        => $tamano,
			'observaciones' => $observaciones,
			'updated_at'    => $now,
		);

		if ( $id > 0 ) {
			$updated = $wpdb->update(
				$table,
				$payload,
				array( 'id' => $id ),
				array( '%s', '%s', '%s', '%s' ),
				array( '%d' )
			);

			if ( false === $updated ) {
				return new WP_Error( 'db_error', __( 'No se pudo actualizar el registro.', 'logistica' ) );
			}
		} else {
			$payload['created_at'] = $now;
			$inserted              = $wpdb->insert(
				$table,
				$payload,
				array( '%s', '%s', '%s', '%s', '%s' )
			);

			if ( ! $inserted ) {
				return new WP_Error( 'db_error', __( 'No se pudo guardar el registro.', 'logistica' ) );
			}

			$id = (int) $wpdb->insert_id;
		}

		$row = self::get_by_id( $id );
		if ( ! $row ) {
			return new WP_Error( 'missing_row', __( 'No se pudo leer el registro guardado.', 'logistica' ) );
		}

		return $row;
	}

	/**
	 * @param int $id Row ID.
	 * @return bool|\WP_Error
	 */
	public static function delete_row( $id ) {
		$id = (int) $id;
		if ( $id <= 0 ) {
			return new WP_Error( 'invalid_id', __( 'Registro no válido.', 'logistica' ) );
		}

		$row = Logistica_Soft_Delete::get_row( 'rotulo_rollos', $id, true );
		if ( ! $row || Logistica_Soft_Delete::row_is_deleted( $row ) ) {
			return new WP_Error( 'not_found', __( 'Registro no encontrado.', 'logistica' ) );
		}

		return Logistica_Soft_Delete::soft_delete( 'rotulo_rollos', $id, $row );
	}
}
