<?php
/**
 * Options Migration
 *
 * Migrates options from old plugin to new plugin structure.
 *
 * @since 2.0.0
 * @package EasyInvoice
 */

namespace EasyInvoice\Migration\Src;

/**
 * Options Migration Class
 *
 * @since 2.0.0
 */
class OptionsMigration extends AbstractMigration {

    /**
     * Old options to migrate.
     * Maps old option names to new option names.
     *
     * @since 2.0.0
     * @var array
     */
    private $old_options = [
        // Core settings
        'easy_invoice_settings' => [
            // Company info
            'company_name' => 'easy_invoice_company_name',
            'company_address' => 'easy_invoice_company_address',
            'company_logo' => 'easy_invoice_company_logo',
            'company_additional_info' => 'easy_invoice_company_additional_info',
            'company_email' => 'easy_invoice_company_email',
            'company_phone' => 'easy_invoice_company_phone',
            'company_website' => 'easy_invoice_company_website',
            'company_vat' => 'easy_invoice_company_vat',
            'company_registration' => 'easy_invoice_company_registration',

            // Currency settings
            'currency_code' => 'easy_invoice_currency_code',
            'currency_symbol' => 'easy_invoice_currency_symbol',
            'currency_position' => 'easy_invoice_currency_position',
            'decimal_separator' => 'easy_invoice_decimal_separator',
            'thousand_separator' => 'easy_invoice_thousands_separator',
            'decimal_precision' => 'easy_invoice_decimal_precision',
            'currency_symbol_type' => 'easy_invoice_currency_symbol_type',

            // Tax settings
            'tax_rate' => 'easy_invoice_tax_rate',
            'tax_name' => 'easy_invoice_tax_name',
            'tax_type' => 'easy_invoice_tax_entry_method',
            'tax_enabled' => 'easy_invoice_tax_enabled',
            'tax_label' => 'easy_invoice_tax_label',
            'tax_number' => 'easy_invoice_tax_number',

            // PDF settings
            'pdf_paper_size' => 'easy_invoice_pdf_paper_size',
            'pdf_font_family' => 'easy_invoice_pdf_font_family',
            'pdf_font_size' => 'easy_invoice_pdf_font_size',
            'pdf_margin_top' => 'easy_invoice_pdf_margin_top',
            'pdf_margin_bottom' => 'easy_invoice_pdf_margin_bottom',
            'pdf_margin_left' => 'easy_invoice_pdf_margin_left',
            'pdf_margin_right' => 'easy_invoice_pdf_margin_right',

            // Template settings
            'invoice_template' => 'easy_invoice_invoice_template',
            'quote_template' => 'easy_invoice_quote_template',
            'template_color' => 'easy_invoice_template_color',
            'template_font' => 'easy_invoice_template_font',
            'template_font_size' => 'easy_invoice_template_font_size',

            // Watermark settings
            'invoice_watermark_type' => 'easy_invoice_pro_invoice_watermark_type',
            'invoice_watermark_text' => 'easy_invoice_pro_invoice_text_watermark',
            'invoice_watermark_image' => 'easy_invoice_pro_invoice_image_watermark',
            'invoice_watermark_opacity' => 'easy_invoice_pro_invoice_watermark_opacity',
            'invoice_watermark_color' => 'easy_invoice_pro_invoice_text_watermark_color',
            'invoice_watermark_size' => 'easy_invoice_pro_invoice_image_watermark_size',
            'quote_watermark_type' => 'easy_invoice_pro_quote_watermark_type',
            'quote_watermark_text' => 'easy_invoice_pro_quote_text_watermark',
            'quote_watermark_image' => 'easy_invoice_pro_quote_image_watermark',
            'quote_watermark_opacity' => 'easy_invoice_pro_quote_watermark_opacity',
            'quote_watermark_color' => 'easy_invoice_pro_quote_text_watermark_color',
            'quote_watermark_size' => 'easy_invoice_pro_quote_image_watermark_size',

            // Client settings
            'client_portal_enabled' => 'easy_invoice_client_portal_enabled',
            'client_registration_enabled' => 'easy_invoice_client_registration_enabled',
            'client_login_redirect' => 'easy_invoice_client_login_redirect',
            'client_registration_redirect' => 'easy_invoice_client_registration_redirect',

            // Notification settings
            'notification_invoice_created' => 'easy_invoice_notification_invoice_created',
            'notification_invoice_sent' => 'easy_invoice_notification_invoice_sent',
            'notification_invoice_viewed' => 'easy_invoice_notification_invoice_viewed',
            'notification_invoice_paid' => 'easy_invoice_notification_invoice_paid',
            'notification_quote_created' => 'easy_invoice_notification_quote_created',
            'notification_quote_sent' => 'easy_invoice_notification_quote_sent',
            'notification_quote_viewed' => 'easy_invoice_notification_quote_viewed',
            'notification_quote_accepted' => 'easy_invoice_notification_quote_accepted',
            'notification_quote_declined' => 'easy_invoice_notification_quote_declined'
        ],

        // Invoice settings
        'easy_invoice_invoice_settings' => [
            'next_number' => 'easy_invoice_next_invoice_number',
            'prefix' => 'easy_invoice_invoice_prefix',
            'starting_number' => 'easy_invoice_invoice_starting_number',
            'due_days' => 'easy_invoice_invoice_due_days',
            'footer_text' => 'easy_invoice_invoice_footer_text',
            'terms_conditions' => 'easy_invoice_invoice_terms_conditions',
            'show_adjust_field' => 'easy_invoice_invoice_show_adjust_field',
            'enable_payment_button' => 'easy_invoice_enable_payment_button',
            'payment_button_link' => 'easy_invoice_payment_button_link'
        ],

        // Quote settings
        'easy_invoice_quote_settings' => [
            'next_number' => 'easy_invoice_next_quote_number',
            'prefix' => 'easy_invoice_quote_prefix',
            'starting_number' => 'easy_invoice_quote_starting_number',
            'footer_text' => 'easy_invoice_quote_footer_text',
            'terms_conditions' => 'easy_invoice_quote_terms_conditions',
            'show_adjust_field' => 'easy_invoice_quote_show_adjust_field',
            'accept_text' => 'easy_invoice_quote_accept_text',
            'accepted_message' => 'easy_invoice_quote_accepted_message',
            'accept_button' => 'easy_invoice_quote_accept_button',
            'accept_action' => 'easy_invoice_quote_accept_action',
            'decline_reason_required' => 'easy_invoice_quote_decline_reason_required',
            'declined_message' => 'easy_invoice_quote_declined_message'
        ],

        // Payment settings
        'easy_invoice_payment_settings' => [
            'paypal_email' => 'easy_invoice_paypal_email',
            'paypal_label' => 'easy_invoice_paypal_label',
            'paypal_mode' => 'easy_invoice_paypal_mode',
            'payment_methods' => 'easy_invoice_payment_methods',
            'thankyou_page' => 'easy_invoice_thankyou_page',
            'payment_terms' => 'easy_invoice_payment_terms',
            'payment_reminder_days' => 'easy_invoice_payment_reminder_days'
        ],

        // Email settings
        'easy_invoice_email_settings' => [
            'from_name' => 'easy_invoice_email_from_name',
            'from_address' => 'easy_invoice_email_from_address',
            'reply_to' => 'easy_invoice_email_reply_to',
            'reply_to_name' => 'easy_invoice_email_reply_to_name',
            'bcc_admin' => 'easy_invoice_bcc_admin',
            'admin_email' => 'easy_invoice_admin_email',
            'enable_styling' => 'easy_invoice_enable_email_styling',
            'logo' => 'easy_invoice_email_logo',
            'footer_text' => 'easy_invoice_email_footer_text',
            'invoice_email_enabled' => 'easy_invoice_invoice_email_enabled',
            'invoice_email_subject' => 'easy_invoice_invoice_email_subject',
            'invoice_email_body' => 'easy_invoice_invoice_email_body',
            'quote_email_enabled' => 'easy_invoice_quote_email_enabled',
            'quote_email_subject' => 'easy_invoice_quote_email_subject',
            'quote_email_body' => 'easy_invoice_quote_email_body',
            'payment_email_enabled' => 'easy_invoice_payment_email_enabled',
            'payment_email_subject' => 'easy_invoice_payment_email_subject',
            'payment_email_body' => 'easy_invoice_payment_email_body',
            'reminder_subject' => 'easy_invoice_reminder_subject',
            'reminder_body' => 'easy_invoice_reminder_body'
        ],

        // Pro settings
        'easy_invoice_pro_settings' => [
            'license_key' => 'easy_invoice_pro_license_key',
            'license_status' => 'easy_invoice_pro_license_status',
            'license_expiry' => 'easy_invoice_pro_license_expiry',
            'license_type' => 'easy_invoice_pro_license_type'
        ],

        // System settings
        'easy_invoice_system_settings' => [
            'version' => 'easy_invoice_version',
            'first_install_time' => 'easy_invoice_first_install_time',
            'post_types_registered' => 'easy_invoice_post_types_registered',
            'last_rewrite_flush' => 'easy_invoice_last_rewrite_flush',
            'flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules'
        ]
    ];

    /**
     * New options mapping.
     * Maps new option names to their actual database names.
     *
     * @since 2.0.0
     * @var array
     */
    private $new_options = [
        // Core settings
        'easy_invoice_version' => 'easy_invoice_version',
        'easy_invoice_currency_code' => 'easy_invoice_currency_code',
        'easy_invoice_tax_rate' => 'easy_invoice_tax_rate',
        'easy_invoice_tax_name' => 'easy_invoice_tax_name',
        'easy_invoice_tax_entry_method' => 'easy_invoice_tax_entry_method',
        'easy_invoice_tax_enabled' => 'easy_invoice_tax_enabled',

        // Business settings
        'easy_invoice_company_name' => 'easy_invoice_company_name',
        'easy_invoice_company_address' => 'easy_invoice_company_address',
        'easy_invoice_company_logo' => 'easy_invoice_company_logo',
        'easy_invoice_company_additional_info' => 'easy_invoice_company_additional_info',
        'easy_invoice_company_email' => 'easy_invoice_company_email',
        'easy_invoice_company_phone' => 'easy_invoice_company_phone',
        'easy_invoice_company_website' => 'easy_invoice_company_website',

        // Invoice settings
        'easy_invoice_next_invoice_number' => 'easy_invoice_next_invoice_number',
        'easy_invoice_invoice_prefix' => 'easy_invoice_invoice_prefix',
        'easy_invoice_invoice_permalink' => 'easy_invoice_invoice_permalink',
        'easy_invoice_invoice_show_adjust_field' => 'easy_invoice_invoice_show_adjust_field',
        'easy_invoice_invoice_footer_text' => 'easy_invoice_invoice_footer_text',
        'easy_invoice_invoice_terms_conditions' => 'easy_invoice_invoice_terms_conditions',
        'easy_invoice_enable_payment_button' => 'easy_invoice_enable_payment_button',
        'easy_invoice_payment_button_link' => 'easy_invoice_payment_button_link',
        'easy_invoice_predefined_items' => 'easy_invoice_predefined_items',
        'easy_invoice_invoice_starting_number' => 'easy_invoice_invoice_starting_number',
        'easy_invoice_invoice_due_days' => 'easy_invoice_invoice_due_days',

        // Quote settings
        'easy_invoice_next_quote_number' => 'easy_invoice_next_quote_number',
        'easy_invoice_quote_prefix' => 'easy_invoice_quote_prefix',
        'easy_invoice_quote_permalink' => 'easy_invoice_quote_permalink',
        'easy_invoice_quote_show_adjust_field' => 'easy_invoice_quote_show_adjust_field',
        'easy_invoice_quote_footer_text' => 'easy_invoice_quote_footer_text',
        'easy_invoice_quote_terms_conditions' => 'easy_invoice_quote_terms_conditions',
        'easy_invoice_quote_accept_text' => 'easy_invoice_quote_accept_text',
        'easy_invoice_quote_accepted_message' => 'easy_invoice_quote_accepted_message',
        'easy_invoice_quote_accept_button' => 'easy_invoice_quote_accept_button',
        'easy_invoice_quote_accept_action' => 'easy_invoice_quote_accept_action',
        'easy_invoice_quote_decline_reason_required' => 'easy_invoice_quote_decline_reason_required',
        'easy_invoice_quote_declined_message' => 'easy_invoice_quote_declined_message',
        'easy_invoice_quote_starting_number' => 'easy_invoice_quote_starting_number',

        // Currency settings
        'easy_invoice_currency_symbol_type' => 'easy_invoice_currency_symbol_type',
        'easy_invoice_decimal_precision' => 'easy_invoice_decimal_precision',
        'easy_invoice_decimal_separator' => 'easy_invoice_decimal_separator',
        'easy_invoice_thousands_separator' => 'easy_invoice_thousands_separator',
        'easy_invoice_currency_position' => 'easy_invoice_currency_position',
        'easy_invoice_currency_symbol' => 'easy_invoice_currency_symbol',

        // Payment settings
        'easy_invoice_paypal_email' => 'easy_invoice_paypal_email',
        'easy_invoice_paypal_label' => 'easy_invoice_paypal_label',
        'easy_invoice_paypal_mode' => 'easy_invoice_paypal_mode',
        'easy_invoice_payment_methods' => 'easy_invoice_payment_methods',
        'easy_invoice_thankyou_page' => 'easy_invoice_thankyou_page',
        'easy_invoice_payment_gateway_order' => 'easy_invoice_payment_gateway_order',

        // Email settings
        'easy_invoice_email_from_address' => 'easy_invoice_email_from_address',
        'easy_invoice_email_from_name' => 'easy_invoice_email_from_name',
        'easy_invoice_email_reply_to' => 'easy_invoice_email_reply_to',
        'easy_invoice_email_reply_to_name' => 'easy_invoice_email_reply_to_name',
        'easy_invoice_enable_email_styling' => 'easy_invoice_enable_email_styling',
        'easy_invoice_email_logo' => 'easy_invoice_email_logo',
        'easy_invoice_email_footer_text' => 'easy_invoice_email_footer_text',
        'easy_invoice_bcc_admin' => 'easy_invoice_bcc_admin',
        'easy_invoice_admin_email' => 'easy_invoice_admin_email',
        'easy_invoice_invoice_email_enabled' => 'easy_invoice_invoice_email_enabled',
        'easy_invoice_invoice_email_subject' => 'easy_invoice_invoice_email_subject',
        'easy_invoice_invoice_email_body' => 'easy_invoice_invoice_email_body',
        'easy_invoice_reminder_subject' => 'easy_invoice_reminder_subject',
        'easy_invoice_reminder_body' => 'easy_invoice_reminder_body',
        'easy_invoice_payment_email_enabled' => 'easy_invoice_payment_email_enabled',
        'easy_invoice_payment_email_subject' => 'easy_invoice_payment_email_subject',
        'easy_invoice_payment_email_body' => 'easy_invoice_payment_email_body',
        'easy_invoice_quote_email_enabled' => 'easy_invoice_quote_email_enabled',
        'easy_invoice_quote_email_subject' => 'easy_invoice_quote_email_subject',
        'easy_invoice_quote_email_body' => 'easy_invoice_quote_email_body',
        'easy_invoice_quote_accepted_subject' => 'easy_invoice_quote_accepted_subject',
        'easy_invoice_quote_accepted_body' => 'easy_invoice_quote_accepted_body',
        'easy_invoice_quote_declined_subject' => 'easy_invoice_quote_declined_subject',
        'easy_invoice_quote_declined_body' => 'easy_invoice_quote_declined_body',

        // System settings
        'easy_invoice_flush_rewrite_rules' => 'easy_invoice_flush_rewrite_rules',
        'easy_invoice_first_install_time' => 'easy_invoice_first_install_time',
        'easy_invoice_post_types_registered' => 'easy_invoice_post_types_registered',
        'easy_invoice_last_rewrite_flush' => 'easy_invoice_last_rewrite_flush',

        // Additional settings
        'easy_invoice_payment_terms' => 'easy_invoice_payment_terms',
        'easy_invoice_payment_reminder_days' => 'easy_invoice_payment_reminder_days',
    ];

    /**
     * Check if migration is needed.
     *
     * @since 2.0.0
     * @return bool
     */
    public function is_needed(): bool {
        // Check if any old options exist
        foreach ( $this->old_options as $old_option => $new_option ) {
            if ( $this->option_exists( $old_option ) ) {
                $this->log( sprintf( 'Found option %s that needs migration', $old_option ) );
                return true;
            }
        }

        return false;
    }

    /**
     * Run the migration.
     *
     * @since 2.0.0
     * @return array
     */
    public function migrate(): array {
        $this->log( 'Starting options migration' );

        try {
            $migrated_count = 0;
            $errors = [];

            foreach ( $this->old_options as $old_option => $new_option ) {
                $result = $this->migrate_option( $old_option, $new_option );

                if ( $result['success'] ) {
                    $migrated_count++;
                    $this->log( sprintf( 'Successfully migrated option %s to %s', $old_option, $new_option ) );
                } else {
                    $errors[] = $result['message'];
                    $this->log( sprintf( 'Failed to migrate option %s: %s', $old_option, $result['message'] ), 'error' );
                }
            }

            if ( empty( $errors ) ) {
                return $this->success_result( sprintf( 'Successfully migrated %d options', $migrated_count ) );
            } else {
                return $this->error_result( 'Options migration completed with errors: ' . implode( ', ', $errors ) );
            }

        } catch ( \Exception $e ) {
            $this->log( 'Options migration failed: ' . $e->getMessage(), 'error' );
            return $this->error_result( 'Options migration failed: ' . $e->getMessage() );
        }
    }

    /**
     * Migrate a specific option.
     *
     * @since 2.0.0
     * @param string $old_option Old option name.
     * @param string $new_option New option name.
     * @return array
     */
    private function migrate_option( string $old_option, string $new_option ): array {
        if ( ! $this->option_exists( $old_option ) ) {
            return [
                'success' => true,
                'message' => sprintf( 'Option %s does not exist', $old_option ),
            ];
        }

        try {
            $option_value = get_option( $old_option );

            if ( $option_value === false ) {
                return [
                    'success' => true,
                    'message' => sprintf( 'Option %s has no value', $old_option ),
                ];
            }

            // Transform option value if needed
            $transformed_value = $this->transform_option_value( $old_option, $option_value );

            // Update new option
            $update_result = $this->update_option_safe( $new_option, $transformed_value );

            if ( $update_result ) {
                // Delete old option after successful migration
                $this->delete_option_safe( $old_option );

                return [
                    'success' => true,
                    'message' => sprintf( 'Successfully migrated option %s', $old_option ),
                ];
            } else {
                return [
                    'success' => false,
                    'message' => sprintf( 'Failed to update new option %s', $new_option ),
                ];
            }

        } catch ( \Exception $e ) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Transform option value for new structure.
     *
     * @since 2.0.0
     * @param string $option_name Option name.
     * @param mixed $option_value Option value.
     * @return mixed
     */
    private function transform_option_value( string $option_name, $option_value ) {
        // Handle nested settings arrays
        if (is_array($option_value)) {
            $transformed = [];

            // Get the mapping for this settings group
            $mappings = $this->old_options[$option_name] ?? [];

            if (!empty($mappings)) {
                foreach ($option_value as $key => $value) {
                    // Check if we have a mapping for this key
                    if (isset($mappings[$key])) {
                        $new_key = $mappings[$key];

                        // Transform the value if needed
                        switch ($key) {
                            case 'payment_methods':
                                $transformed[$new_key] = $this->transform_payment_methods($value);
                                break;

                            case 'tax_type':
                                $transformed[$new_key] = $this->transform_tax_type($value);
                                break;

                            case 'currency_position':
                                $transformed[$new_key] = $this->transform_currency_position($value);
                                break;

            default:
                                $transformed[$new_key] = $value;
                        }
                    }
                }
            }

            return $transformed;
        }

                return $option_value;
    }

    /**
     * Transform tax type value.
     *
     * @param string $value Old tax type value
     * @return string New tax type value
     */
    private function transform_tax_type($value) {
        $map = [
            'inclusive' => 'inclusive',
            'exclusive' => 'exclusive',
            'none' => 'none'
        ];

        return $map[$value] ?? 'exclusive';
    }

    /**
     * Transform currency position value.
     *
     * @param string $value Old currency position value
     * @return string New currency position value
     */
    private function transform_currency_position($value) {
        $map = [
            'left' => 'before',
            'right' => 'after',
            'left_space' => 'before_space',
            'right_space' => 'after_space'
        ];

        return $map[$value] ?? 'before';
    }

    /**
     * Transform payment methods array.
     *
     * @param array $methods Old payment methods array
     * @return array New payment methods array
     */
    private function transform_payment_methods($methods) {
        if (!is_array($methods)) {
            return [];
        }

        $transformed = [];
        foreach ($methods as $method) {
            if (is_array($method)) {
                $transformed[] = [
                    'id' => $method['id'] ?? '',
                    'name' => $method['name'] ?? '',
                    'description' => $method['description'] ?? '',
                    'enabled' => isset($method['enabled']) ? (bool)$method['enabled'] : true,
                    'settings' => $method['settings'] ?? []
                ];
            }
        }

        return $transformed;
    }

    /**
     * Transform settings option.
     *
     * @since 2.0.0
     * @param mixed $settings Settings value.
     * @return mixed
     */
    private function transform_settings( $settings ) {
        if ( ! is_array( $settings ) ) {
            return $settings;
        }

        // Add any specific settings transformations here
        // For example, rename keys, restructure arrays, etc.

        return $settings;
    }

    /**
     * Transform email settings option.
     *
     * @since 2.0.0
     * @param mixed $email_settings Email settings value.
     * @return mixed
     */
    private function transform_email_settings( $email_settings ) {
        if ( ! is_array( $email_settings ) ) {
            return $email_settings;
        }

        // Add any specific email settings transformations here

        return $email_settings;
    }


}
