<?php
/**
 * Freefactu Snapshot Utility
 *
 * Utility functions for managing invoice snapshots
 *
 * @package Freefactu
 */

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

class Freefactu_Snapshot_Utility {

    /**
     * Create snapshot for an existing invoice.
     *
     * What this function does:
     * - Creates a JSON snapshot of invoice data from current order state
     * - Validates that order and invoice exist
     * - Checks if snapshot already exists (prevents overwriting)
     * - Uses PDF generator to prepare template data
     * - Saves snapshot to database
     * - WARNING: Uses CURRENT order state, not historical state
     *
     * Where it's called from:
     * - Not currently used in production code (available for manual snapshot creation)
     * - Could be called from admin interface or CLI tools
     *
     * @param int $order_id Order ID
     * @return bool|WP_Error True on success, WP_Error on failure
     */
    public static function create_snapshot_for_order( $order_id ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return new WP_Error( 'invalid_order', __( 'Order not found.', 'freefactu' ) );
        }

        // Check if invoice exists in database
        $invoice_db = Freefactu_DB::get_invoice_by_order_id( $order_id );
        if ( ! $invoice_db ) {
            return new WP_Error( 'no_invoice', __( 'No Verifactu invoice found for this order.', 'freefactu' ) );
        }

        // Check if snapshot already exists
        if ( ! empty( $invoice_db->invoice_snapshot ) ) {
            return new WP_Error( 'snapshot_exists', __( 'Snapshot already exists for this invoice.', 'freefactu' ) );
        }

        // Create snapshot using PDF generator
        $pdf_generator = Freefactu_Factory::create_generator( $order );
        $template_data = $pdf_generator->prepare_template_data();
        $snapshot_json = wp_json_encode( $template_data );

        // Save to database
        $result = Freefactu_DB::update_invoice_snapshot( $order_id, $snapshot_json );

        if ( $result === false ) {
            return new WP_Error( 'save_failed', __( 'Failed to save snapshot to database.', 'freefactu' ) );
        }

        Freefactu_Logger::log( "Snapshot created for order #{$order_id}", 'info' );
        return true;
    }

    /**
     * Bulk create snapshots for all invoices without snapshots.
     *
     * What this function does:
     * - Finds all invoices that have CSV but no snapshot
     * - Creates snapshots for up to $limit invoices
     * - Tracks success/error counts
     * - Returns detailed results array
     * - WARNING: Uses CURRENT order states, not historical states
     *
     * Where it's called from:
     * - Not currently used in production code (available for bulk operations)
     * - Could be called from admin interface or CLI tools
     *
     * @param int $limit Maximum number of invoices to process (default: 100)
     * @return array Results array with success/error counts
     */
    public static function bulk_create_snapshots( $limit = 100 ) {
        // Get invoices without snapshots
        $invoices = Freefactu_DB::get_invoices_needing_snapshot( $limit );

        $results = array(
            'total' => count( $invoices ),
            'success' => 0,
            'errors' => 0,
            'skipped' => 0,
            'messages' => array()
        );

        foreach ( $invoices as $invoice ) {
            $result = self::create_snapshot_for_order( $invoice->order_id );

            if ( is_wp_error( $result ) ) {
                $results['errors']++;
                $results['messages'][] = sprintf(
                    'Order #%d: %s',
                    $invoice->order_id,
                    $result->get_error_message()
                );
            } else {
                $results['success']++;
            }
        }

        return $results;
    }

    /**
     * Verify snapshot data matches current order data.
     *
     * What this function does:
     * - Compares snapshot data with current order data
     * - Checks total amount, item count, and customer name
     * - Returns array with matches flag and list of differences
     * - Useful for detecting if order was modified after invoice was sent
     *
     * Where it's called from:
     * - Not currently used in production code (available for verification)
     * - Could be called from admin interface or debugging tools
     *
     * @param int $order_id Order ID
     * @return array|WP_Error Comparison results or WP_Error
     */
    public static function verify_snapshot( $order_id ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return new WP_Error( 'invalid_order', __( 'Order not found.', 'freefactu' ) );
        }

        // Get snapshot from database
        $invoice_db = Freefactu_DB::get_invoice_by_order_id( $order_id );
        if ( ! $invoice_db || empty( $invoice_db->invoice_snapshot ) ) {
            return new WP_Error( 'no_snapshot', __( 'No snapshot found for this invoice.', 'freefactu' ) );
        }

        $snapshot = json_decode( $invoice_db->invoice_snapshot, true );
        if ( ! $snapshot ) {
            return new WP_Error( 'invalid_snapshot', __( 'Snapshot data is corrupted.', 'freefactu' ) );
        }

        // Get current order data
        $pdf_generator = Freefactu_Factory::create_generator( $order );
        $current_data = $pdf_generator->prepare_template_data();

        // Compare key fields
        $differences = array();

        // Compare totals
        if ( $snapshot['totals']['total'] != $current_data['totals']['total'] ) {
            $differences['total'] = array(
                'snapshot' => $snapshot['totals']['total'],
                'current' => $current_data['totals']['total']
            );
        }

        // Compare item count
        if ( count( $snapshot['items'] ) != count( $current_data['items'] ) ) {
            $differences['item_count'] = array(
                'snapshot' => count( $snapshot['items'] ),
                'current' => count( $current_data['items'] )
            );
        }

        // Compare customer name
        if ( $snapshot['customer']['name'] != $current_data['customer']['name'] ) {
            $differences['customer_name'] = array(
                'snapshot' => $snapshot['customer']['name'],
                'current' => $current_data['customer']['name']
            );
        }

        return array(
            'matches' => empty( $differences ),
            'differences' => $differences,
            'snapshot_date' => $invoice_db->created_at
        );
    }

    /**
     * Get snapshot data for an order.
     *
     * What this function does:
     * - Retrieves invoice snapshot from database
     * - Decodes JSON snapshot data
     * - Validates snapshot exists and is valid JSON
     * - Returns snapshot array or WP_Error
     *
     * Where it's called from:
     * - Not currently used in production code (available for snapshot retrieval)
     * - Could be called from admin interface or debugging tools
     *
     * @param int $order_id Order ID
     * @return array|WP_Error Snapshot data or WP_Error
     */
    public static function get_snapshot( $order_id ) {
        $invoice_db = Freefactu_DB::get_invoice_by_order_id( $order_id );

        if ( ! $invoice_db ) {
            return new WP_Error( 'no_invoice', __( 'No Verifactu invoice found for this order.', 'freefactu' ) );
        }

        if ( empty( $invoice_db->invoice_snapshot ) ) {
            return new WP_Error( 'no_snapshot', __( 'No snapshot found for this invoice.', 'freefactu' ) );
        }

        $snapshot = json_decode( $invoice_db->invoice_snapshot, true );

        if ( ! $snapshot ) {
            return new WP_Error( 'invalid_snapshot', __( 'Snapshot data is corrupted.', 'freefactu' ) );
        }

        return $snapshot;
    }

    /**
     * Delete snapshot for an order.
     *
     * What this function does:
     * - Removes snapshot data from database
     * - Sets invoice_snapshot field to empty string
     * - Logs the deletion
     * - Returns true on success or WP_Error on failure
     *
     * Where it's called from:
     * - Not currently used in production code (available for snapshot management)
     * - Could be called from admin interface or cleanup tools
     *
     * @param int $order_id Order ID
     * @return bool|WP_Error True on success, WP_Error on failure
     */
    public static function delete_snapshot( $order_id ) {
        $result = Freefactu_DB::update_invoice_snapshot( $order_id, '' );

        if ( $result === false ) {
            return new WP_Error( 'delete_failed', __( 'Failed to delete snapshot.', 'freefactu' ) );
        }

        Freefactu_Logger::log( "Snapshot deleted for order #{$order_id}", 'info' );
        return true;
    }

    /**
     * Get statistics about snapshots.
     *
     * What this function does:
     * - Counts total invoices in database
     * - Counts invoices with snapshots
     * - Counts invoices without snapshots (but with CSV)
     * - Calculates percentage of invoices with snapshots
     * - Returns statistics array
     *
     * Where it's called from:
     * - Not currently used in production code (available for reporting)
     * - Could be called from admin dashboard or status pages
     *
     * @return array Statistics array with counts and percentage
     */
    public static function get_statistics() {
        $total_invoices    = Freefactu_DB::count_invoices();
        $with_snapshots    = Freefactu_DB::count_invoices_with_snapshots();
        $without_snapshots = Freefactu_DB::count_invoices_needing_snapshots();

        return array(
            'total_invoices' => (int) $total_invoices,
            'with_snapshots' => (int) $with_snapshots,
            'without_snapshots' => (int) $without_snapshots,
            'percentage' => $total_invoices > 0 ? round( ( $with_snapshots / $total_invoices ) * 100, 2 ) : 0
        );
    }
}
