<?php
/**
 * Trazabilidad para entidades almacenadas en wp_options (no tablas SQL).
 *
 * @package Logistica
 */

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

/**
 * Elimina lógicamente ítems de options: papelera + auditoría, sin DELETE SQL.
 */
class Logistica_Option_Lifecycle {

	/**
	 * @param string               $module_key   Módulo registrado.
	 * @param string               $entity_type  Tipo de entidad.
	 * @param string               $entity_id    ID estable.
	 * @param string               $entity_label Etiqueta visible.
	 * @param array<string, mixed> $payload      Snapshot completo para restaurar.
	 * @param callable             $remove       Callback que quita el ítem del option activo.
	 * @return true|WP_Error
	 */
	public static function delete( $module_key, $entity_type, $entity_id, $entity_label, $payload, $remove ) {
		if ( ! Logistica_Entity_Lifecycle::can_soft_delete() ) {
			return new WP_Error( 'forbidden', __( 'No tienes permiso para eliminar registros.', 'logistica' ) );
		}

		if ( ! is_callable( $remove ) ) {
			return new WP_Error( 'invalid_remove', __( 'No se puede completar la eliminación.', 'logistica' ) );
		}

		$payload['_storage'] = 'option';

		Logistica_Entity_Lifecycle::record_delete(
			$module_key,
			$entity_type,
			(string) $entity_id,
			$payload,
			$entity_label
		);

		call_user_func( $remove );

		return true;
	}

	/**
	 * Restaura una entidad option-based desde papelera.
	 *
	 * @param string               $module_key  Módulo.
	 * @param string               $entity_type Tipo.
	 * @param string               $entity_id   ID.
	 * @param array<string, mixed> $payload     Snapshot.
	 * @return true|WP_Error
	 */
	public static function restore( $module_key, $entity_type, $entity_id, $payload ) {
		if ( empty( $payload['_storage'] ) || 'option' !== $payload['_storage'] ) {
			return new WP_Error( 'invalid_payload', __( 'Payload de restauración no válido.', 'logistica' ) );
		}

		$key = $module_key . ':' . $entity_type;

		switch ( $key ) {
			case 'pedidos_board:board':
				return self::restore_pedidos_board( $payload );

			case 'configuracion:conversion_template':
				return self::restore_conversion_template( $payload );

			case 'planeacion_impresion:machine':
				return self::restore_planning_machine( $payload, 'planeacion_impresion', Logistica_Print_Planning::class );

			case 'planeacion_formado:machine':
				return self::restore_planning_machine( $payload, 'planeacion_formado', Logistica_Forming_Planning::class );

			case 'etiqueta_catalog:opcion':
				return self::restore_etiqueta_opcion( $payload );

			case 'conversion_tables:state':
			case 'conversion_tables:sheet_row':
				return Logistica_Conversion_Tables::restore_from_payload( $entity_type, $entity_id, $payload );

			default:
				return new WP_Error( 'unsupported', __( 'Restauración no soportada para este tipo.', 'logistica' ) );
		}
	}

	/**
	 * @param array<string, mixed> $payload Snapshot.
	 * @return true|WP_Error
	 */
	private static function restore_pedidos_board( $payload ) {
		$board = $payload['board'] ?? null;
		if ( ! is_array( $board ) || empty( $board['slug'] ) ) {
			return new WP_Error( 'missing_board', __( 'No hay datos del tablero para restaurar.', 'logistica' ) );
		}

		$boards = Logistica_Pedidos_Board::get_boards();
		foreach ( $boards as $existing ) {
			if ( (string) ( $existing['slug'] ?? '' ) === (string) $board['slug'] ) {
				return true;
			}
		}

		$boards[] = array(
			'slug'  => sanitize_title( (string) $board['slug'] ),
			'label' => sanitize_text_field( (string) ( $board['label'] ?? $board['slug'] ) ),
		);

		if ( ! Logistica_Pedidos_Board::save_boards( $boards ) ) {
			return new WP_Error( 'restore_failed', __( 'No se pudo restaurar el tablero de pedidos.', 'logistica' ) );
		}

		return true;
	}

	/**
	 * @param array<string, mixed> $payload Snapshot.
	 * @return true|WP_Error
	 */
	private static function restore_conversion_template( $payload ) {
		$type     = sanitize_key( (string) ( $payload['sheet_type'] ?? '' ) );
		$template = $payload['template'] ?? null;

		if ( '' === $type || ! is_array( $template ) ) {
			return new WP_Error( 'missing_template', __( 'No hay datos de plantilla para restaurar.', 'logistica' ) );
		}

		$saved = get_option( 'logistica_conversion_templates', array() );
		if ( ! is_array( $saved ) ) {
			$saved = array();
		}
		if ( ! isset( $saved[ $type ] ) || ! is_array( $saved[ $type ] ) ) {
			$saved[ $type ] = array();
		}

		$template_id = (string) ( $template['id'] ?? '' );
		foreach ( $saved[ $type ] as $item ) {
			if ( (string) ( $item['id'] ?? '' ) === $template_id ) {
				return true;
			}
		}

		$saved[ $type ][] = $template;
		update_option( 'logistica_conversion_templates', $saved, false );

		return true;
	}

	/**
	 * @param array<string, mixed> $payload      Snapshot.
	 * @param string               $table_key    Clave de tabla planeación.
	 * @param class-string         $planning_cls Clase de planeación.
	 * @return true|WP_Error
	 */
	private static function restore_planning_machine( $payload, $table_key, $planning_cls ) {
		$slug = sanitize_key( (string) ( $payload['slug'] ?? '' ) );
		if ( '' === $slug ) {
			return new WP_Error( 'missing_slug', __( 'Máquina no válida.', 'logistica' ) );
		}

		if ( ! empty( $payload['is_default'] ) ) {
			$hidden = $planning_cls::get_hidden_default_machine_slugs();
			$hidden = array_values(
				array_filter(
					$hidden,
					static function ( $item ) use ( $slug ) {
						return sanitize_key( (string) $item ) !== $slug;
					}
				)
			);
			update_option( $planning_cls::HIDDEN_DEFAULT_MACHINES_OPTION, $hidden, false );

			if ( ! empty( $payload['label_override'] ) ) {
				$overrides = get_option( $planning_cls::MACHINE_LABEL_OVERRIDES_OPTION, array() );
				if ( ! is_array( $overrides ) ) {
					$overrides = array();
				}
				$override_label = is_array( $payload['label_override'] )
					? (string) ( $payload['label_override']['label'] ?? '' )
					: (string) $payload['label_override'];
				if ( '' !== $override_label ) {
					$overrides[ $slug ] = $override_label;
					update_option( $planning_cls::MACHINE_LABEL_OVERRIDES_OPTION, $overrides, false );
				}
			}
		} elseif ( ! empty( $payload['custom_machine'] ) && is_array( $payload['custom_machine'] ) ) {
			$custom = get_option( $planning_cls::CUSTOM_MACHINES_OPTION, array() );
			if ( ! is_array( $custom ) ) {
				$custom = array();
			}
			$custom[ $slug ] = sanitize_text_field( (string) ( $payload['custom_machine']['label'] ?? $slug ) );
			update_option( $planning_cls::CUSTOM_MACHINES_OPTION, $custom, false );
		}

		$schedules = $payload['schedules'] ?? array();
		if ( is_array( $schedules ) ) {
			foreach ( $schedules as $schedule_row ) {
				if ( ! is_array( $schedule_row ) || empty( $schedule_row['id'] ) ) {
					continue;
				}
				Logistica_Soft_Delete::restore_from_payload( $table_key, (int) $schedule_row['id'], $schedule_row );
			}
		}

		return true;
	}

	/**
	 * @param array<string, mixed> $payload Snapshot.
	 * @return true|WP_Error
	 */
	private static function restore_etiqueta_opcion( $payload ) {
		$kind = sanitize_key( (string) ( $payload['kind'] ?? '' ) );
		$key  = (string) ( $payload['key'] ?? '' );

		if ( 'tamano' === $kind ) {
			$key = Logistica_Label_Etiqueta_Tamanos::normalize_label( $key );
		} else {
			$key = sanitize_key( $key );
		}

		if ( '' === $kind || '' === $key ) {
			return new WP_Error( 'missing_opcion', __( 'No hay datos de la opción para restaurar.', 'logistica' ) );
		}

		return Logistica_Label_Option_Lifecycle::restore_from_payload( $kind, $key, $payload );
	}
}
