<?php
/**
 * Import Tracking Service - Tracks created/updated items for rollback.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Modules\Imports\Service;

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

final class ImportTrackingService {

    const META_KEY_IMPORT_ID = '_mt_primelink_import_id';
    const META_KEY_IMPORT_TIME = '_mt_primelink_import_time';
    const OPTION_KEY_TRACKING = 'mt_primelink_import_tracking_';

    /**
     * Track a created item.
     *
     * @param int    $import_id Import ID.
     * @param int    $item_id   Item ID (product/order/customer ID).
     * @param string $item_type Item type ('product', 'order', 'customer', 'coupon').
     * @return bool
     */
    public static function track_created( $import_id, $item_id, $item_type = 'product' ) {
        $import_id = absint( $import_id );
        $item_id   = absint( $item_id );
        if ( $import_id < 1 || $item_id < 1 ) {
            return false;
        }

        $tracking = self::get_tracking( $import_id );
        if ( ! isset( $tracking['created'][ $item_type ] ) ) {
            $tracking['created'][ $item_type ] = array();
        }
        if ( ! in_array( $item_id, $tracking['created'][ $item_type ], true ) ) {
            $tracking['created'][ $item_type ][] = $item_id;
        }

        // Store import ID and time on the item
        update_post_meta( $item_id, self::META_KEY_IMPORT_ID, $import_id );
        update_post_meta( $item_id, self::META_KEY_IMPORT_TIME, current_time( 'mysql' ) );

        return self::save_tracking( $import_id, $tracking );
    }

    /**
     * Track an updated item with backup data.
     *
     * @param int    $import_id Import ID.
     * @param int    $item_id   Item ID.
     * @param string $item_type Item type.
     * @param array  $backup_data Backup data (pre-update state).
     * @return bool
     */
    public static function track_updated( $import_id, $item_id, $item_type = 'product', $backup_data = null ) {
        $import_id = absint( $import_id );
        $item_id   = absint( $item_id );
        if ( $import_id < 1 || $item_id < 1 ) {
            return false;
        }

        $tracking = self::get_tracking( $import_id );
        if ( ! isset( $tracking['updated'][ $item_type ] ) ) {
            $tracking['updated'][ $item_type ] = array();
        }

        // If not already tracked, create backup
        if ( ! isset( $tracking['updated'][ $item_type ][ $item_id ] ) ) {
            if ( $backup_data === null ) {
                $backup_data = self::create_backup( $item_id, $item_type );
            }
            $tracking['updated'][ $item_type ][ $item_id ] = $backup_data;
        }

        return self::save_tracking( $import_id, $tracking );
    }

    /**
     * Create backup of item data before update.
     *
     * @param int    $item_id   Item ID.
     * @param string $item_type Item type.
     * @return array
     */
    private static function create_backup( $item_id, $item_type ) {
        $backup = array(
            'item_id'   => $item_id,
            'item_type' => $item_type,
            'timestamp' => current_time( 'mysql' ),
        );

        switch ( $item_type ) {
            case 'product':
                $product = wc_get_product( $item_id );
                if ( ! $product ) {
                    return $backup;
                }

                $post = get_post( $item_id );
                $backup['data'] = array(
                    'post' => array(
                        'post_title'   => $post->post_title ?? '',
                        'post_content' => $post->post_content ?? '',
                        'post_excerpt' => $post->post_excerpt ?? '',
                        'post_status'  => $post->post_status ?? 'publish',
                    ),
                    'product' => array(
                        'sku'            => $product->get_sku(),
                        'regular_price'  => $product->get_regular_price(),
                        'sale_price'     => $product->get_sale_price(),
                        'stock_quantity' => $product->get_stock_quantity(),
                        'stock_status'   => $product->get_stock_status(),
                        'weight'         => $product->get_weight(),
                        'length'         => $product->get_length(),
                        'width'          => $product->get_width(),
                        'height'         => $product->get_height(),
                        'product_type'   => $product->get_type(),
                    ),
                    'taxonomies' => array(),
                    'meta'       => array(),
                    'attributes' => array(),
                );

                // Taxonomies
                $taxonomies = get_object_taxonomies( 'product' );
                foreach ( $taxonomies as $tax ) {
                    $terms = wp_get_post_terms( $item_id, $tax, array( 'fields' => 'names' ) );
                    if ( ! empty( $terms ) ) {
                        $backup['data']['taxonomies'][ $tax ] = $terms;
                    }
                }

                // Meta
                $meta = get_post_meta( $item_id );
                foreach ( $meta as $key => $values ) {
                    if ( strpos( $key, '_' ) === 0 && strpos( $key, '_mt_primelink_' ) !== 0 ) {
                        $backup['data']['meta'][ $key ] = count( $values ) === 1 ? $values[0] : $values;
                    }
                }

                // Attributes
                $attributes = $product->get_attributes();
                if ( ! empty( $attributes ) ) {
                    foreach ( $attributes as $attr_name => $attr ) {
                        $backup['data']['attributes'][ $attr_name ] = array(
                            'values'    => $attr->get_options(),
                            'visible'   => $attr->get_visible(),
                            'variation' => $attr->get_variation(),
                        );
                    }
                }

                // Featured image
                $thumbnail_id = get_post_thumbnail_id( $item_id );
                if ( $thumbnail_id ) {
                    $backup['data']['featured_image'] = $thumbnail_id;
                }

                // Gallery images
                $gallery = get_post_meta( $item_id, '_product_image_gallery', true );
                if ( $gallery ) {
                    $backup['data']['gallery'] = $gallery;
                }
                break;

            case 'order':
                $order = wc_get_order( $item_id );
                if ( ! $order ) {
                    return $backup;
                }

                $backup['data'] = array(
                    'status'         => $order->get_status(),
                    'date_created'   => $order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d H:i:s' ) : '',
                    'total'          => $order->get_total(),
                    'currency'      => $order->get_currency(),
                    'billing'        => $order->get_billing_address(),
                    'shipping'       => $order->get_shipping_address(),
                    'customer_id'    => $order->get_customer_id(),
                    'customer_email' => $order->get_billing_email(),
                );
                break;

            case 'customer':
                $customer = new \WC_Customer( $item_id );
                if ( ! $customer->get_id() ) {
                    return $backup;
                }

                $backup['data'] = array(
                    'email'      => $customer->get_email(),
                    'username'   => $customer->get_username(),
                    'first_name' => $customer->get_first_name(),
                    'last_name'  => $customer->get_last_name(),
                    'billing'    => $customer->get_billing(),
                    'shipping'   => $customer->get_shipping(),
                    'meta'       => array(),
                );

                // Backup customer meta
                $meta = get_user_meta( $item_id );
                foreach ( $meta as $key => $values ) {
                    if ( strpos( $key, '_' ) === 0 && strpos( $key, '_mt_primelink_' ) !== 0 ) {
                        $backup['data']['meta'][ $key ] = count( $values ) === 1 ? $values[0] : $values;
                    }
                }
                break;
        }

        return $backup;
    }

    /**
     * Get tracking data for an import.
     *
     * @param int $import_id Import ID.
     * @return array
     */
    public static function get_tracking( $import_id ) {
        $import_id = absint( $import_id );
        $data      = get_option( self::OPTION_KEY_TRACKING . $import_id, array() );

        return wp_parse_args( $data, array(
            'created' => array(),
            'updated' => array(),
        ) );
    }

    /**
     * Save tracking data.
     *
     * @param int   $import_id Import ID.
     * @param array $tracking  Tracking data.
     * @return bool
     */
    private static function save_tracking( $import_id, $tracking ) {
        $import_id = absint( $import_id );
        return update_option( self::OPTION_KEY_TRACKING . $import_id, $tracking, false );
    }

    /**
     * Rollback an import - restore/delete items.
     *
     * @param int  $import_id Import ID.
     * @param bool $delete_created If true, delete created items. If false, keep them.
     * @param bool $restore_updated If true, restore updated items to previous state.
     * @return array Results.
     */
    public static function rollback( $import_id, $delete_created = true, $restore_updated = true ) {
        $import_id = absint( $import_id );
        $tracking  = self::get_tracking( $import_id );

        $results = array(
            'deleted'  => 0,
            'restored' => 0,
            'errors'   => 0,
        );

        // Delete created items
        if ( $delete_created ) {
            foreach ( $tracking['created'] ?? array() as $item_type => $item_ids ) {
                foreach ( $item_ids as $item_id ) {
                    try {
                        switch ( $item_type ) {
                            case 'product':
                                wp_delete_post( $item_id, true );
                                break;
                            case 'order':
                                $order = wc_get_order( $item_id );
                                if ( $order ) {
                                    $order->delete( true );
                                }
                                break;
                            case 'customer':
                                wp_delete_user( $item_id );
                                break;
                            case 'coupon':
                                wp_delete_post( $item_id, true );
                                break;
                        }
                        $results['deleted']++;
                    } catch ( \Throwable $e ) {
                        $results['errors']++;
                    }
                }
            }
        }

        // Restore updated items
        if ( $restore_updated ) {
            foreach ( $tracking['updated'] ?? array() as $item_type => $items ) {
                foreach ( $items as $item_id => $backup ) {
                    try {
                        self::restore_item( $item_id, $item_type, $backup );
                        $results['restored']++;
                    } catch ( \Throwable $e ) {
                        $results['errors']++;
                    }
                }
            }
        }

        // Clear tracking after rollback
        delete_option( self::OPTION_KEY_TRACKING . $import_id );

        return $results;
    }

    /**
     * Restore an item to its previous state.
     *
     * @param int    $item_id   Item ID.
     * @param string $item_type Item type.
     * @param array  $backup    Backup data.
     * @return bool
     */
    private static function restore_item( $item_id, $item_type, $backup ) {
        if ( empty( $backup['data'] ) ) {
            return false;
        }

        switch ( $item_type ) {
            case 'product':
                $data = $backup['data'];
                $post = get_post( $item_id );
                if ( ! $post ) {
                    return false;
                }

                // Restore post data
                if ( ! empty( $data['post'] ) ) {
                    wp_update_post( array(
                        'ID'           => $item_id,
                        'post_title'   => $data['post']['post_title'] ?? $post->post_title,
                        'post_content' => $data['post']['post_content'] ?? $post->post_content,
                        'post_excerpt' => $data['post']['post_excerpt'] ?? $post->post_excerpt,
                        'post_status'  => $data['post']['post_status'] ?? $post->post_status,
                    ) );
                }

                $product = wc_get_product( $item_id );
                if ( ! $product ) {
                    return false;
                }

                // Restore product data
                if ( ! empty( $data['product'] ) ) {
                    $prod_data = $data['product'];
                    if ( isset( $prod_data['sku'] ) ) {
                        $product->set_sku( $prod_data['sku'] );
                    }
                    if ( isset( $prod_data['regular_price'] ) ) {
                        $product->set_regular_price( $prod_data['regular_price'] );
                    }
                    if ( isset( $prod_data['sale_price'] ) ) {
                        $product->set_sale_price( $prod_data['sale_price'] );
                    }
                    if ( isset( $prod_data['stock_quantity'] ) ) {
                        $product->set_stock_quantity( $prod_data['stock_quantity'] );
                    }
                    if ( isset( $prod_data['stock_status'] ) ) {
                        $product->set_stock_status( $prod_data['stock_status'] );
                    }
                    if ( isset( $prod_data['weight'] ) ) {
                        $product->set_weight( $prod_data['weight'] );
                    }
                    if ( isset( $prod_data['length'] ) ) {
                        $product->set_length( $prod_data['length'] );
                    }
                    if ( isset( $prod_data['width'] ) ) {
                        $product->set_width( $prod_data['width'] );
                    }
                    if ( isset( $prod_data['height'] ) ) {
                        $product->set_height( $prod_data['height'] );
                    }
                    $product->save();
                }

                // Restore taxonomies
                if ( ! empty( $data['taxonomies'] ) ) {
                    foreach ( $data['taxonomies'] as $tax => $terms ) {
                        wp_set_object_terms( $item_id, $terms, $tax, false );
                    }
                }

                // Restore meta
                if ( ! empty( $data['meta'] ) ) {
                    foreach ( $data['meta'] as $key => $value ) {
                        update_post_meta( $item_id, $key, $value );
                    }
                }

                // Restore attributes
                if ( ! empty( $data['attributes'] ) ) {
                    $attrs = array();
                    foreach ( $data['attributes'] as $name => $attr_data ) {
                        $attr = new \WC_Product_Attribute();
                        $attr->set_name( $name );
                        $attr->set_options( $attr_data['values'] ?? array() );
                        $attr->set_visible( $attr_data['visible'] ?? true );
                        $attr->set_variation( $attr_data['variation'] ?? false );
                        $attrs[] = $attr;
                    }
                    $product->set_attributes( $attrs );
                    $product->save();
                }

                // Restore images
                if ( isset( $data['featured_image'] ) ) {
                    set_post_thumbnail( $item_id, $data['featured_image'] );
                }
                if ( isset( $data['gallery'] ) ) {
                    update_post_meta( $item_id, '_product_image_gallery', $data['gallery'] );
                }
                break;

            case 'order':
                $order = wc_get_order( $item_id );
                if ( ! $order ) {
                    return false;
                }

                $data = $backup['data'];
                if ( ! empty( $data['status'] ) ) {
                    $order->set_status( $data['status'] );
                }
                if ( ! empty( $data['total'] ) ) {
                    $order->set_total( $data['total'] );
                }
                $order->save();
                break;

            case 'customer':
                $customer = new \WC_Customer( $item_id );
                if ( ! $customer->get_id() ) {
                    return false;
                }

                $data = $backup['data'];
                if ( ! empty( $data['email'] ) ) {
                    $customer->set_email( $data['email'] );
                }
                if ( ! empty( $data['first_name'] ) ) {
                    $customer->set_first_name( $data['first_name'] );
                }
                if ( ! empty( $data['last_name'] ) ) {
                    $customer->set_last_name( $data['last_name'] );
                }
                if ( ! empty( $data['billing'] ) ) {
                    $customer->set_billing( $data['billing'] );
                }
                if ( ! empty( $data['shipping'] ) ) {
                    $customer->set_shipping( $data['shipping'] );
                }
                $customer->save();

                // Restore meta
                if ( ! empty( $data['meta'] ) ) {
                    foreach ( $data['meta'] as $key => $value ) {
                        update_user_meta( $item_id, $key, $value );
                    }
                }
                break;
        }

        return true;
    }

    /**
     * Check if an import can be rolled back.
     *
     * @param int $import_id Import ID.
     * @return bool
     */
    public static function can_rollback( $import_id ) {
        $tracking = self::get_tracking( $import_id );
        $has_created = ! empty( $tracking['created'] );
        $has_updated = ! empty( $tracking['updated'] );
        return $has_created || $has_updated;
    }

    /**
     * Get rollback summary.
     *
     * @param int $import_id Import ID.
     * @return array
     */
    public static function get_rollback_summary( $import_id ) {
        $tracking = self::get_tracking( $import_id );

        $summary = array(
            'created' => array(),
            'updated' => array(),
            'total_created' => 0,
            'total_updated' => 0,
        );

        foreach ( $tracking['created'] ?? array() as $type => $ids ) {
            $summary['created'][ $type ] = count( $ids );
            $summary['total_created'] += count( $ids );
        }

        foreach ( $tracking['updated'] ?? array() as $type => $items ) {
            $summary['updated'][ $type ] = count( $items );
            $summary['total_updated'] += count( $items );
        }

        return $summary;
    }
}

