<?php
/**
 * Adjuntar Factura en Correos Extension
 *
 * This extension automatically attaches invoice PDFs to WooCommerce
 * order emails based on user configuration.
 *
 * @package Freefactu
 * @subpackage Extensions/AdjuntarFacturaCorreo
 * @since 1.2.0
 */

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

/**
 * Class Freefactu_Email_Attachment
 *
 * Main class for the "Adjuntar Factura en Correos" extension.
 * Handles:
 * - Automatic PDF attachment to WooCommerce emails
 * - Configurable email types (customer_completed_order, customer_invoice, etc.)
 * - Custom attachment naming
 * - Extension settings within the Configuración tab
 *
 * @since 1.2.0
 */
class Freefactu_Email_Attachment {

    /**
     * The single instance of this class.
     *
     * @var Freefactu_Email_Attachment|null
     */
    private static $instance = null;

    /**
     * Extension ID.
     *
     * @var string
     */
    const EXTENSION_ID = 'adjuntar-factura-correo';

    /**
     * Option key for extension settings.
     *
     * @var string
     */
    const OPTION_KEY = 'freefactu_email_attachment_settings';

    /**
     * Get the singleton instance.
     *
     * @return Freefactu_Email_Attachment
     */
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor.
     */
    private function __construct() {
        $this->init_hooks();
    }

    /**
     * Initialize hooks.
     */
    private function init_hooks() {
        // Hook into WooCommerce email attachments
        add_filter( 'woocommerce_email_attachments', array( $this, 'attach_invoice_to_email' ), 10, 4 );

        // Add settings section to Configuración tab
        add_action( 'freefactu_settings_sections', array( $this, 'render_settings_section' ), 20 );

        // Register extension settings
        add_action( 'admin_init', array( $this, 'register_settings' ) );

        // Add settings to sanitization allowlist
        add_filter( 'freefactu_sanitize_settings_keys', array( $this, 'add_settings_keys' ) );
    }

    /**
     * Get extension settings.
     *
     * @return array Settings array with defaults.
     */
    public static function get_settings() {
        $defaults = array(
            'enabled'                     => true,
            'attach_to_customer_completed'=> true,
            'attach_to_customer_invoice'  => true,
            'attach_to_customer_processing' => false,
            'attach_to_customer_on_hold'  => false,
            'attach_to_customer_refunded' => false,
            'attach_to_admin_new_order'   => false,
            'attachment_name_format'      => 'factura-{invoice_number}',
            'only_when_pdf_exists'        => true,
        );

        $settings = get_option( self::OPTION_KEY, array() );
        
        return wp_parse_args( $settings, $defaults );
    }

    /**
     * Update extension settings.
     *
     * @param array $settings Settings to save.
     * @return bool True if updated successfully.
     */
    public static function update_settings( $settings ) {
        return update_option( self::OPTION_KEY, $settings );
    }

    /**
     * Register extension settings for WordPress Settings API.
     */
    public function register_settings() {
        register_setting( 
            'freefactu_settings_group', 
            self::OPTION_KEY, 
            array( $this, 'sanitize_settings' ) 
        );
    }

    /**
     * Sanitize extension settings.
     *
     * @param array $input Raw input from form.
     * @return array Sanitized settings.
     */
    public function sanitize_settings( $input ) {
        $sanitized = array();

        // Boolean fields
        $boolean_fields = array(
            'enabled',
            'attach_to_customer_completed',
            'attach_to_customer_invoice',
            'attach_to_customer_processing',
            'attach_to_customer_on_hold',
            'attach_to_customer_refunded',
            'attach_to_admin_new_order',
            'only_when_pdf_exists',
        );

        foreach ( $boolean_fields as $field ) {
            $sanitized[ $field ] = ! empty( $input[ $field ] );
        }

        // Text fields
        if ( isset( $input['attachment_name_format'] ) ) {
            $sanitized['attachment_name_format'] = sanitize_text_field( $input['attachment_name_format'] );
        }

        return $sanitized;
    }

    /**
     * Add extension setting keys to the allowlist.
     *
     * @param array $keys Existing keys.
     * @return array Modified keys.
     */
    public function add_settings_keys( $keys ) {
        $keys[] = self::OPTION_KEY;
        return $keys;
    }

    /**
     * Attach invoice PDF to WooCommerce emails.
     *
     * @param array  $attachments Existing attachments.
     * @param string $email_id    Email identifier.
     * @param mixed  $order       Order object or order data.
     * @param object $email       Email object.
     * @return array Modified attachments.
     */
    public function attach_invoice_to_email( $attachments, $email_id, $order, $email = null ) {
        // Log entry point
        $this->log( "=== Email Attachment Hook Triggered ===" );
        $this->log( "Email ID: " . $email_id );
        
        // Safely get order type for logging
        $order_type = 'null';
        if ( is_object( $order ) ) {
            $order_type = get_class( $order );
        } elseif ( is_array( $order ) ) {
            $order_type = 'array (not an order object)';
        }
        $this->log( "Order type: " . $order_type );
        $this->log( "Existing attachments count: " . count( $attachments ) );

        // Check if extension is enabled
        $settings = self::get_settings();
        $this->log( "Extension enabled: " . ( ! empty( $settings['enabled'] ) ? 'YES' : 'NO' ) );
        
        if ( empty( $settings['enabled'] ) ) {
            $this->log( "SKIP: Extension is disabled" );
            return $attachments;
        }

        // Validate order object - must be a WC_Order instance
        if ( ! is_object( $order ) || ! is_a( $order, 'WC_Order' ) ) {
            $this->log( "SKIP: Invalid order object (not WC_Order). Some email types like 'backorder' don't pass order objects." );
            return $attachments;
        }

        $order_id = $order->get_id();
        $this->log( "Order ID: " . $order_id );
        $this->log( "Order status: " . $order->get_status() );

        // Check if this email type should have attachments
        $should_attach = $this->should_attach_to_email( $email_id, $settings );
        $this->log( "Should attach to '{$email_id}': " . ( $should_attach ? 'YES' : 'NO' ) );
        
        if ( ! $should_attach ) {
            $this->log( "SKIP: Email type '{$email_id}' not configured for attachments" );
            $this->log( "Configured email types: " . $this->get_configured_email_types_debug( $settings ) );
            return $attachments;
        }

        // Check if Freefactu_DB exists
        if ( ! class_exists( 'Freefactu_DB' ) ) {
            $this->log( "SKIP: Freefactu_DB class not found" );
            return $attachments;
        }

        $invoice = Freefactu_DB::get_invoice_by_order_id( $order_id );
        $this->log( "Invoice found: " . ( $invoice ? 'YES' : 'NO' ) );
        
        if ( ! $invoice ) {
            $this->log( "SKIP: No invoice found for order {$order_id}" );
            return $attachments;
        }

        $this->log( "Invoice number: " . ( isset( $invoice->invoice_number ) ? $invoice->invoice_number : 'N/A' ) );
        $this->log( "Invoice status: " . ( isset( $invoice->status ) ? $invoice->status : 'N/A' ) );

        // Check if invoice has a PDF
        $pdf_path = isset( $invoice->pdf_path ) ? $invoice->pdf_path : '';
        $this->log( "PDF path in DB: " . ( $pdf_path ? $pdf_path : '(empty)' ) );
        
        if ( empty( $pdf_path ) ) {
            $this->log( "SKIP: No PDF path stored in invoice record" );
            if ( ! empty( $settings['only_when_pdf_exists'] ) ) {
                $this->log( "only_when_pdf_exists is enabled, skipping" );
            }
            return $attachments;
        }

        // Convert to absolute path
        if ( class_exists( 'Freefactu_Filesystem' ) ) {
            $absolute_path = Freefactu_Filesystem::to_absolute_path( $pdf_path );
        } else {
            $upload_dir = wp_upload_dir();
            $absolute_path = $upload_dir['basedir'] . '/' . $pdf_path;
        }
        $this->log( "Absolute PDF path: " . $absolute_path );

        // Verify file exists
        $file_exists = file_exists( $absolute_path );
        $this->log( "PDF file exists: " . ( $file_exists ? 'YES' : 'NO' ) );
        
        if ( ! $file_exists ) {
            $this->log( "SKIP: PDF file not found at path" );
            return $attachments;
        }

        $this->log( "PDF file size: " . filesize( $absolute_path ) . " bytes" );

        // Generate custom filename if needed
        $filename = $this->generate_attachment_filename( $invoice, $settings );
        $this->log( "Generated filename: " . ( $filename ? $filename : '(using original)' ) );
        
        // If we need a custom filename, copy to temp location with new name
        if ( $filename ) {
            $temp_path = $this->create_temp_attachment( $absolute_path, $filename );
            $this->log( "Temp file created: " . ( $temp_path ? $temp_path : 'FAILED' ) );
            
            if ( $temp_path ) {
                $attachments[] = $temp_path;
                // Schedule cleanup
                add_action( 'shutdown', function() use ( $temp_path ) {
                    if ( file_exists( $temp_path ) ) {
                        wp_delete_file( $temp_path );
                    }
                } );
            } else {
                $this->log( "WARNING: Failed to create temp file, using original path" );
                $attachments[] = $absolute_path;
            }
        } else {
            $attachments[] = $absolute_path;
        }

        $this->log( "SUCCESS: PDF attached to email" );
        $this->log( "Final attachments count: " . count( $attachments ) );
        $this->log( "=== Email Attachment Hook Complete ===" );

        /**
         * Filter attachments before sending email.
         *
         * @param array    $attachments Modified attachments array.
         * @param object   $invoice     Invoice database object.
         * @param WC_Order $order       WooCommerce order object.
         * @param string   $email_id    Email identifier.
         */
        return apply_filters( 'freefactu_email_attachments', $attachments, $invoice, $order, $email_id );
    }

    /**
     * Log a message to the Freefactu debug log.
     *
     * @param string $message Message to log.
     */
    private function log( $message ) {
        if ( class_exists( 'Freefactu_Logger' ) ) {
            Freefactu_Logger::log( '[Email Attachment] ' . $message, 'debug' );
        }
    }

    /**
     * Get debug string of configured email types.
     *
     * @param array $settings Extension settings.
     * @return string Debug string.
     */
    private function get_configured_email_types_debug( $settings ) {
        $types = array();
        
        if ( ! empty( $settings['attach_to_customer_completed'] ) ) {
            $types[] = 'customer_completed_order';
        }
        if ( ! empty( $settings['attach_to_customer_invoice'] ) ) {
            $types[] = 'customer_invoice';
        }
        if ( ! empty( $settings['attach_to_customer_processing'] ) ) {
            $types[] = 'customer_processing_order';
        }
        if ( ! empty( $settings['attach_to_customer_on_hold'] ) ) {
            $types[] = 'customer_on_hold_order';
        }
        if ( ! empty( $settings['attach_to_customer_refunded'] ) ) {
            $types[] = 'customer_refunded_order';
        }
        if ( ! empty( $settings['attach_to_admin_new_order'] ) ) {
            $types[] = 'new_order';
        }
        
        return empty( $types ) ? '(none configured)' : implode( ', ', $types );
    }

    /**
     * Check if PDF should be attached to this email type.
     *
     * @param string $email_id Email identifier.
     * @param array  $settings Extension settings.
     * @return bool True if should attach.
     */
    private function should_attach_to_email( $email_id, $settings ) {
        $email_mapping = array(
            'customer_completed_order' => 'attach_to_customer_completed',
            'customer_invoice'         => 'attach_to_customer_invoice',
            'customer_processing_order'=> 'attach_to_customer_processing',
            'customer_on_hold_order'   => 'attach_to_customer_on_hold',
            'customer_refunded_order'  => 'attach_to_customer_refunded',
            'new_order'                => 'attach_to_admin_new_order',
        );

        if ( ! isset( $email_mapping[ $email_id ] ) ) {
            return false;
        }

        $setting_key = $email_mapping[ $email_id ];
        return ! empty( $settings[ $setting_key ] );
    }

    /**
     * Generate attachment filename based on format.
     *
     * @param object $invoice  Invoice database object.
     * @param array  $settings Extension settings.
     * @return string|null Filename or null for default.
     */
    private function generate_attachment_filename( $invoice, $settings ) {
        if ( empty( $settings['attachment_name_format'] ) ) {
            return null;
        }

        $format = $settings['attachment_name_format'];
        
        // Replace placeholders
        $replacements = array(
            '{invoice_number}' => isset( $invoice->invoice_number ) ? $invoice->invoice_number : '',
            '{order_id}'       => isset( $invoice->order_id ) ? $invoice->order_id : '',
            '{date}'           => isset( $invoice->invoice_date ) ? gmdate( 'Y-m-d', strtotime( $invoice->invoice_date ) ) : gmdate( 'Y-m-d' ),
        );

        $filename = str_replace( array_keys( $replacements ), array_values( $replacements ), $format );
        
        // Sanitize filename
        $filename = sanitize_file_name( $filename );
        
        // Ensure .pdf extension
        if ( substr( $filename, -4 ) !== '.pdf' ) {
            $filename .= '.pdf';
        }

        return $filename;
    }

    /**
     * Create temporary attachment with custom filename.
     *
     * @param string $source_path Original PDF path.
     * @param string $filename    New filename.
     * @return string|false Temp file path or false on failure.
     */
    private function create_temp_attachment( $source_path, $filename ) {
        $temp_dir = get_temp_dir();
        $temp_path = $temp_dir . $filename;

        if ( copy( $source_path, $temp_path ) ) {
            return $temp_path;
        }

        return false;
    }

    /**
     * Render settings section in Configuración tab.
     * This is called via the 'freefactu_settings_sections' action.
     */
    public function render_settings_section() {
        // Check if extension is active
        if ( ! class_exists( 'Freefactu_Extensions' ) || 
             ! Freefactu_Extensions::is_extension_active( self::EXTENSION_ID ) ) {
            return;
        }

        $settings = self::get_settings();
        ?>
        <!-- ================================================================
             SECTION: Adjuntar Factura en Correos (Extension)
             ================================================================ -->
        <div class="freefactu-settings-section freefactu-extension-section">
            <h2>
                <span class="dashicons dashicons-email"></span>
                <?php esc_html_e( 'Adjuntar Factura en Correos', 'freefactu' ); ?>
                <span class="freefactu-extension-badge"><?php esc_html_e( 'Extensión', 'freefactu' ); ?></span>
            </h2>
            <p class="description freefactu-settings-section__description">
                <?php esc_html_e( 'Adjunta automáticamente el PDF de la factura a los correos electrónicos de WooCommerce.', 'freefactu' ); ?>
            </p>

            <table class="form-table">
                <tr>
                    <th scope="row">
                        <label for="email_attachment_enabled">
                            <?php esc_html_e( 'Activar adjuntos', 'freefactu' ); ?>
                        </label>
                    </th>
                    <td>
                        <label>
                            <input type="checkbox" id="email_attachment_enabled" 
                                   name="<?php echo esc_attr( self::OPTION_KEY ); ?>[enabled]" value="1" 
                                   <?php checked( ! empty( $settings['enabled'] ) ); ?>>
                            <?php esc_html_e( 'Adjuntar PDF de factura a los correos electrónicos', 'freefactu' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Activa o desactiva el adjunto de facturas en todos los correos configurados.', 'freefactu' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">
                        <?php esc_html_e( 'Tipos de correo', 'freefactu' ); ?>
                    </th>
                    <td>
                        <fieldset>
                            <legend class="screen-reader-text"><?php esc_html_e( 'Tipos de correo', 'freefactu' ); ?></legend>
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_customer_completed]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_customer_completed'] ) ); ?>>
                                <?php esc_html_e( 'Pedido completado (customer_completed_order)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Cuando el pedido se marca como completado', 'freefactu' ); ?></span>
                            </label>
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_customer_invoice]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_customer_invoice'] ) ); ?>>
                                <?php esc_html_e( 'Factura del cliente (customer_invoice)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Correo de factura manual', 'freefactu' ); ?></span>
                            </label>
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_customer_processing]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_customer_processing'] ) ); ?>>
                                <?php esc_html_e( 'Pedido en proceso (customer_processing_order)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Cuando el pago se confirma', 'freefactu' ); ?></span>
                            </label>
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_customer_on_hold]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_customer_on_hold'] ) ); ?>>
                                <?php esc_html_e( 'Pedido en espera (customer_on_hold_order)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Cuando el pedido está pendiente de pago', 'freefactu' ); ?></span>
                            </label>
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_customer_refunded]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_customer_refunded'] ) ); ?>>
                                <?php esc_html_e( 'Pedido reembolsado (customer_refunded_order)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Cuando se realiza un reembolso', 'freefactu' ); ?></span>
                            </label>
                            
                            <hr class="freefactu-form-separator">
                            
                            <label class="freefactu-extension-form-label">
                                <input type="checkbox" 
                                       name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attach_to_admin_new_order]" value="1"
                                       <?php checked( ! empty( $settings['attach_to_admin_new_order'] ) ); ?>>
                                <?php esc_html_e( 'Nuevo pedido para admin (new_order)', 'freefactu' ); ?>
                                <span class="description freefactu-extension-form-description">– <?php esc_html_e( 'Correo de notificación al administrador', 'freefactu' ); ?></span>
                            </label>
                        </fieldset>
                        <p class="description freefactu-form-note">
                            <?php esc_html_e( 'Selecciona en qué tipos de correo deseas adjuntar el PDF de la factura.', 'freefactu' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">
                        <label for="email_attachment_name_format">
                            <?php esc_html_e( 'Nombre del archivo', 'freefactu' ); ?>
                        </label>
                    </th>
                    <td>
                        <?php $name_format = isset( $settings['attachment_name_format'] ) ? $settings['attachment_name_format'] : 'factura-{invoice_number}'; ?>
                        <input type="text" id="email_attachment_name_format" 
                               name="<?php echo esc_attr( self::OPTION_KEY ); ?>[attachment_name_format]" 
                               value="<?php echo esc_attr( $name_format ); ?>" class="regular-text">
                        <p class="description">
                            <?php esc_html_e( 'Formato del nombre del archivo adjunto. Variables disponibles:', 'freefactu' ); ?><br>
                            <code>{invoice_number}</code> – <?php esc_html_e( 'Número de factura', 'freefactu' ); ?><br>
                            <code>{order_id}</code> – <?php esc_html_e( 'ID del pedido', 'freefactu' ); ?><br>
                            <code>{date}</code> – <?php esc_html_e( 'Fecha de la factura (YYYY-MM-DD)', 'freefactu' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row">
                        <label for="email_attachment_only_pdf">
                            <?php esc_html_e( 'Opciones avanzadas', 'freefactu' ); ?>
                        </label>
                    </th>
                    <td>
                        <label>
                            <input type="checkbox" id="email_attachment_only_pdf" 
                                   name="<?php echo esc_attr( self::OPTION_KEY ); ?>[only_when_pdf_exists]" value="1" 
                                   <?php checked( ! empty( $settings['only_when_pdf_exists'] ) ); ?>>
                            <?php esc_html_e( 'Solo adjuntar cuando exista PDF', 'freefactu' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Si está marcado, no se adjuntará nada si el PDF de la factura no existe. Si está desmarcado, se enviará el correo sin adjunto.', 'freefactu' ); ?>
                        </p>
                    </td>
                </tr>
            </table>
        </div>
        <?php
    }

    /**
     * Check if extension is properly activated and should run.
     *
     * @return bool True if extension should be active.
     */
    public static function is_active() {
        if ( ! class_exists( 'Freefactu_Extensions' ) ) {
            return false;
        }
        return Freefactu_Extensions::is_extension_active( self::EXTENSION_ID );
    }
}

// Initialize the extension only if active
if ( class_exists( 'Freefactu_Extensions' ) && Freefactu_Extensions::is_extension_active( 'adjuntar-factura-correo' ) ) {
    Freefactu_Email_Attachment::instance();
}
