<?php
/**
 * Hooks de restauración y utilidades de trazabilidad por módulo.
 *
 * @package Logistica
 */

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

/**
 * Conecta papelera e historial de versiones con las entidades del dominio.
 */
class Logistica_Lifecycle_Hooks {

	/**
	 * @return void
	 */
	public static function init() {
		add_action( 'logistica_lifecycle_restore', array( __CLASS__, 'handle_restore' ), 10, 5 );
		add_action( 'logistica_lifecycle_restore_version', array( __CLASS__, 'handle_restore_version' ), 10, 5 );
	}

	/**
	 * Restaura un registro desde la papelera.
	 *
	 * @param string               $module_key  Módulo.
	 * @param string               $entity_type Tipo.
	 * @param string               $entity_id   ID.
	 * @param array<string, mixed> $payload     Snapshot.
	 * @param array<string, mixed> $row         Fila papelera.
	 * @return void
	 */
	public static function handle_restore( $module_key, $entity_type, $entity_id, $payload, $row ) {
		unset( $row );

		if ( ! Logistica_Entity_Lifecycle::can_restore() ) {
			return;
		}

		if ( ! empty( $payload['_storage'] ) && 'option' === $payload['_storage'] ) {
			Logistica_Option_Lifecycle::restore( $module_key, $entity_type, $entity_id, $payload );
			return;
		}

		$table_key = Logistica_Soft_Delete::table_key_for_entity( $module_key, $entity_type );
		if ( ! $table_key ) {
			return;
		}

		$result = Logistica_Soft_Delete::restore_from_payload( $table_key, (int) $entity_id, $payload );
		if ( is_wp_error( $result ) ) {
			return;
		}

		if ( 'warehouse' === $module_key && 'item' === $entity_type ) {
			$restored = Logistica_Soft_Delete::get_row( $table_key, (int) $entity_id, true );
			if ( $restored && 'activo' === ( $restored['estado'] ?? '' ) ) {
				Logistica_Warehouse_Inventory::sync_lote_to_cierre_bases(
					(string) ( $restored['codigo'] ?? '' ),
					(string) ( $restored['lote'] ?? '' )
				);
			}
		}
	}

	/**
	 * Restaura una versión anterior de una entidad tabular.
	 *
	 * @param string               $module_key  Módulo.
	 * @param string               $entity_type Tipo.
	 * @param string               $entity_id   ID.
	 * @param array<string, mixed> $payload     Snapshot.
	 * @param array<string, mixed> $version     Metadatos versión.
	 * @return void
	 */
	public static function handle_restore_version( $module_key, $entity_type, $entity_id, $payload, $version ) {
		unset( $version );

		if ( ! Logistica_Entity_Lifecycle::can_restore() ) {
			return;
		}

		if ( ! empty( $payload['_storage'] ) && 'option' === $payload['_storage'] ) {
			Logistica_Option_Lifecycle::restore( $module_key, $entity_type, $entity_id, $payload );
			return;
		}

		if ( 'cierre_ordenes' === $module_key && 'config' === $entity_type && is_array( $payload ) ) {
			update_option( Logistica_Order_Closing::OPTION, $payload, false );
			return;
		}

		if ( 'conversion_tables' === $module_key && in_array( $entity_type, array( 'state', 'sheet_row' ), true ) ) {
			Logistica_Conversion_Tables::restore_from_payload( $entity_type, $entity_id, $payload );
			return;
		}

		if ( 'minutas' === $module_key && 'bulk_import' === $entity_type && is_array( $payload ) ) {
			self::restore_minutas_bulk( $payload );
			return;
		}

		$table_key = Logistica_Soft_Delete::table_key_for_entity( $module_key, $entity_type );
		if ( ! $table_key || empty( $payload ) ) {
			return;
		}

		global $wpdb;

		$table = Logistica_Database::table( $table_key );
		if ( ! $table ) {
			return;
		}

		unset( $payload['is_deleted'], $payload['deleted_at'], $payload['deleted_by'] );
		$payload['id']         = (int) $entity_id;
		$payload['updated_at'] = current_time( 'mysql' );

		$wpdb->replace( $table, $payload );

		if ( 'warehouse' === $module_key && 'item' === $entity_type ) {
			Logistica_Warehouse_Inventory::sync_lote_to_cierre_bases(
				(string) ( $payload['codigo'] ?? '' ),
				(string) ( $payload['lote'] ?? '' )
			);
		}
	}

	/**
	 * Restaura snapshot masivo de minutas desde historial de versiones.
	 *
	 * @param array<int, array<string, mixed>> $rows Filas guardadas.
	 * @return void
	 */
	private static function restore_minutas_bulk( $rows ) {
		if ( ! is_array( $rows ) || empty( $rows ) ) {
			return;
		}

		global $wpdb;

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

		$active_ids = $wpdb->get_col(
			'SELECT id FROM ' . $table . ' WHERE ' . Logistica_Soft_Delete::sql_not_deleted( 'minutas' ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		);
		if ( is_array( $active_ids ) && ! empty( $active_ids ) ) {
			Logistica_Soft_Delete::mark_deleted_batch(
				'minutas',
				array_map( 'intval', $active_ids )
			);
		}

		foreach ( $rows as $row ) {
			if ( ! is_array( $row ) || empty( $row['id'] ) ) {
				continue;
			}
			unset( $row['is_deleted'], $row['deleted_at'], $row['deleted_by'] );
			$row['updated_at'] = current_time( 'mysql' );
			$wpdb->replace( $table, $row );
		}
	}
}
