<?php
/**
 * Invoice Field Registration Class
 *
 * @package     EasyInvoice
 * @author      Your Name
 * @copyright   Copyright (c) 2023, Your Company
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.0.0
 */

namespace EasyInvoice\Forms\Invoice;

use EasyInvoice\Forms\BaseFieldRegistration;

/**
 * Invoice Field Registration
 *
 * Handles registration of invoice-specific form fields, tabs, and templates.
 *
 * @since 1.0.0
 */
class InvoiceFieldRegistration extends BaseFieldRegistration {
    
    /**
     * Register default tabs
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultTabs(): void {
        // Define all tabs in a single array for easy modification by pro plugins
        $all_tabs = $this->getDefaultTabsArray();
        
        // Apply filter to allow pro plugins to modify tabs
        $all_tabs = apply_filters('easy_invoice_invoice_form_tabs', $all_tabs);
        
        // Register all tabs from the array
        foreach ($all_tabs as $tab_id => $tab_config) {
            $this->registerTab($tab_id, $tab_config);
        }
    }

    /**
     * Get default tabs array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultTabsArray(): array {
        return [
            'invoice-tab' => [
                'label' => __('Invoice Details', 'easy-invoice'),
                'icon' => 'fas fa-file-invoice',
                'active' => true,
                'order' => 1
            ],
            'items-tab' => [
                'label' => __('Items', 'easy-invoice'),
                'icon' => 'fas fa-list',
                'active' => false,
                'order' => 2
            ],
            'client-tab' => [
                'label' => __('Client', 'easy-invoice'),
                'icon' => 'fas fa-user',
                'active' => false,
                'order' => 3
            ],
            'discounts-taxes-tab' => [
                'label' => __('Discounts & Taxes', 'easy-invoice'),
                'icon' => 'fas fa-percentage',
                'active' => false,
                'order' => 4
            ],
            'payments-tab' => [
                'label' => __('Payment', 'easy-invoice'),
                'icon' => 'fas fa-credit-card',
                'active' => false,
                'order' => 5
            ]
        ];
    }

    /**
     * Register default fields
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultFields(): void {
        // Define all fields in a single array for easy modification by pro plugins
        $all_fields = $this->getDefaultFieldsArray();
        
        // Apply filter to allow pro plugins to modify fields
        $all_fields = apply_filters('easy_invoice_invoice_fields', $all_fields);
        
        // Register all fields from the array
        foreach ($all_fields as $field_config) {
            $this->registerField($field_config['tab_id'], $field_config);
        }
    }

    /**
     * Get default fields array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultFieldsArray(): array {
        return [
            // Invoice Tab Fields
            [
                'tab_id' => 'invoice-tab',
                'name' => 'invoice_template',
                'type' => 'hidden',
                'label' => __('Invoice Template', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'order' => 0,
                'default_value' => 'standard',
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice template is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'title',
                'type' => 'text',
                'label' => __('Invoice Title', 'easy-invoice'),
                'placeholder' => __('Enter invoice title', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-6',
                'order' => 1,
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice title is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'description',
                'type' => 'textarea',
                'label' => __('Invoice Description', 'easy-invoice'),
                'placeholder' => __('Enter invoice description or additional details', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'order' => 2,
                'description' => __('Optional description or additional details about this invoice.', 'easy-invoice'),
                'sanitize_callback' => 'sanitize_textarea_field',
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'number',
                'type' => 'text',
                'label' => __('Invoice Number', 'easy-invoice'),
                'placeholder' => __('INV-001', 'easy-invoice'),
                'required' => true,
                'readonly' => true,
                'description' => __('This is the unique number for your invoice. It cannot be changed.', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'order' => 3,
                'default_value' => function() {
                    // For new invoices, show the next number without incrementing
                    // For existing invoices, this will be overridden by the invoice object's getNumber() method
                    if (class_exists('\\EasyInvoice\\Services\\InvoiceNumberService')) {
                        $service = new \EasyInvoice\Services\InvoiceNumberService();
                        return $service->getNextNumber();
                    }
                    return 'INV-' . str_pad(time(), 6, '0', STR_PAD_LEFT);
                },
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice number is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'issue_date',
                'type' => 'date',
                'label' => __('Issue Date', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'order' => 4,
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty($value) && strtotime($value) ? true : __('Please enter a valid issue date.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'due_date',
                'type' => 'date',
                'label' => __('Due Date', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'order' => 5,
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty($value) && strtotime($value) ? true : __('Please enter a valid due date.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'status',
                'type' => 'select',
                'label' => __('Status', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'options' => [
                    'available' => __('Available', 'easy-invoice'),
                    'draft' => __('Draft', 'easy-invoice'),
                    'overdue' => __('Overdue', 'easy-invoice'),
                    'paid' => __('Paid', 'easy-invoice'),
                    'unpaid' => __('Unpaid', 'easy-invoice'),
                    'cancelled' => __('Cancelled', 'easy-invoice')
                ],
                'order' => 6
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'notes',
                'type' => 'textarea',
                'label' => __('Notes', 'easy-invoice'),
                'placeholder' => __('Additional notes for the client', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 6,
                'description' => __('These notes will be visible to your client on the invoice.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'internal_notes',
                'type' => 'textarea',
                'label' => __('Internal Notes', 'easy-invoice'),
                'placeholder' => __('Internal notes (not visible to client)', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 7,
                'description' => __('Only you and your team can see these notes. Clients will not see them.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'terms',
                'type' => 'textarea',
                'label' => __('Payment Terms', 'easy-invoice'),
                'placeholder' => __('Payment terms and conditions', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 8,
                'default_value' => function() {
                    return \EasyInvoice\Controllers\SettingsController::getInvoiceTermsConditions();
                },
                'description' => __('Specify the payment terms and conditions for this invoice.', 'easy-invoice'),
            ],


            // Client Tab Fields
            [
                'tab_id' => 'client-tab',
                'name' => 'client_id',
                'type' => 'select',
                'label' => __('Select Client', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'options' => $this->getClientOptions(),
                'order' => 1,
                'description' => __('Choose an existing client or add a new one.', 'easy-invoice'),
            ],

            // Discounts & Taxes Tab Fields
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_type',
                'type' => 'select',
                'label' => __('Discount Type', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-2',
                'section' => 'discount',
                'options' => [
                    'none' => __('No Discount', 'easy-invoice'),
                    'percentage' => __('Percentage', 'easy-invoice'),
                    'fixed' => __('Fixed Amount', 'easy-invoice')
                ],
                'order' => 1,
                'description' => __('Choose how the discount should be applied to this invoice.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_value',
                'type' => 'number',
                'label' => __('Discount Value', 'easy-invoice'),
                'placeholder' => '0.00',
                'grid_cols' => 'sm:col-span-2',
                'section' => 'discount',
                'min' => '0',
                'step' => '0.01',
                'order' => 2,
                'sanitize_callback' => 'floatval',
                'validate_callback' => function($value) {
                    return is_numeric($value) && $value >= 0 ? true : __('Discount value must be a non-negative number.', 'easy-invoice');
                },
                'description' => __('Enter the discount amount or percentage for this invoice.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_calculation_method',
                'type' => 'select',
                'label' => __('Calculation Method', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-2',
                'section' => 'tax',
                'options' => [
                    'before_tax' => __('Before Tax', 'easy-invoice'),
                    'after_tax' => __('After Tax', 'easy-invoice')
                ],
                'order' => 3,
                'description' => __('Apply discount before tax (reduces taxable amount) or after tax (tax on full amount)', 'easy-invoice'),
            ],
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'tax_rate',
                'type' => 'number',
                'label' => __('Tax Rate (%)', 'easy-invoice'),
                'placeholder' => '0.00',
                'grid_cols' => 'sm:col-span-3',
                'section' => 'tax',
                'min' => '0',
                'max' => '100',
                'step' => '0.01',
                'order' => 4,
                'default_value' => function() {
                    return easy_invoice_get_tax_rate();
                },
                'sanitize_callback' => 'floatval',
                'validate_callback' => function($value) {
                    return is_numeric($value) && $value >= 0 && $value <= 100 ? true : __('Tax rate must be between 0 and 100.', 'easy-invoice');
                },
                'description' => __('The tax rate that will be applied to taxable items in this invoice.', 'easy-invoice'),
            ],
            
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'prices_include_tax',
                'type' => 'select',
                'label' => __('Price Includes Tax', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'tax',
                'options' => [
                    'no' => __('No', 'easy-invoice'),
                    'yes' => __('Yes', 'easy-invoice')
                ],
                'order' => 4,
                'description' => __('Choose whether the prices in this invoice include tax or not.', 'easy-invoice'),
            ],

            // Payments Tab Fields
            [
                'tab_id' => 'payments-tab',
                'name' => 'payment_gateways',
                'type' => 'payment_gateways',
                'label' => __('Payment Gateways', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-12',
                'section' => 'payment',
                'order' => 1
            ],
            [
                'tab_id' => 'payments-tab',
                'name' => 'payment_gateways_toggle_state',
                'type' => 'hidden',
                'label' => __('Payment Gateways Toggle State', 'easy-invoice'),
                'default_value' => '0',
                'section' => 'payment',
                'order' => 2
            ],

            // Currency Section in Payment Tab
            [
                'tab_id' => 'payments-tab',
                'name' => 'currency_code',
                'type' => 'select',
                'label' => __('Currency', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'currency',
                'options' => array_merge(
                    ['global' => __('Use from Global Settings', 'easy-invoice')],
                    \EasyInvoice\Helpers\CurrencyHelper::getCurrencyOptions()
                ),
                'default_value' => 'global',
                'order' => 2,
                'description' => __('Select the currency for this invoice or use global settings.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'payments-tab',
                'name' => 'currency_position',
                'type' => 'select',
                'label' => __('Currency Symbol Position', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'currency',
                'options' => [
                    'global' => __('Use from Global Settings', 'easy-invoice'),
                    'before' => __('Before Amount', 'easy-invoice'),
                    'after' => __('After Amount', 'easy-invoice'),
                ],
                'default_value' => 'global',
                'order' => 3,
                'description' => __('Choose where to display the currency symbol or use global setting.', 'easy-invoice'),
            ],
        ];
    }

    /**
     * Register default templates
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultTemplates(): void {
        // Define all templates in a single array for easy modification by pro plugins
        $all_templates = $this->getDefaultTemplatesArray();
        
        // Apply filter to allow pro plugins to modify templates
        $all_templates = apply_filters('easy_invoice_invoice_templates', $all_templates);
        
        // Register all templates from the array
        foreach ($all_templates as $template_id => $template_config) {
            $this->registerTemplate($template_id, $template_config);
        }
    }

    /**
     * Get default templates array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultTemplatesArray(): array {
        // Check if this is the free version (no pro plugin active)
        $is_free_version = !easy_invoice_has_pro();
        
        return [
            'standard' => [
                'name' => __('Standard', 'easy-invoice'),
                'icon' => 'fas fa-file-invoice',
                'description' => __('Clean and professional standard template', 'easy-invoice'),
                'order' => 1,
                'is_free' => true
            ],
            'legacy' => [
                'name' => __('Legacy', 'easy-invoice'),
                'icon' => 'fas fa-file-alt',
                'description' => __('Clean, minimalist design with traditional business layout', 'easy-invoice'),
                'order' => 2,
                'is_free' => true
            ],
            'professional' => [
                'name' => __('Professional', 'easy-invoice'),
                'icon' => 'fas fa-briefcase',
                'description' => __('Professional business template with modern design', 'easy-invoice'),
                'order' => 3,
                'is_free' => !$is_free_version
            ],
            'modern' => [
                'name' => __('Modern', 'easy-invoice'),
                'icon' => 'fas fa-rocket',
                'description' => __('Modern and sleek design template', 'easy-invoice'),
                'order' => 4,
                'is_free' => !$is_free_version
            ]
        ];
    }

    /**
     * Register default item fields
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultItemFields(): void {
        // Define all item fields in a single array for easy modification by pro plugins
        $all_item_fields = $this->getDefaultItemFieldsArray();
        
        // Apply filter to allow pro plugins to modify item fields
        $all_item_fields = apply_filters('easy_invoice_invoice_item_fields', $all_item_fields);
        
        // Register all item fields from the array
        foreach ($all_item_fields as $field_config) {
            $this->registerItemField($field_config);
        }
    }

    /**
     * Get default item fields array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultItemFieldsArray(): array {
        $fields = [
            [
                'name' => 'title',
                'type' => 'text',
                'label' => __('Item Title', 'easy-invoice'),
                'placeholder' => __('Enter item title', 'easy-invoice'),
                'required' => true,
                'container_class' => 'sm:col-span-6',
                'order' => 1,
                'description' => __('A short name for this item (e.g. Service Fee, Product Name).', 'easy-invoice'),
            ],
            [
                'name' => 'description',
                'type' => 'textarea',
                'label' => __('Description', 'easy-invoice'),
                'placeholder' => __('Enter item description', 'easy-invoice'),
                'container_class' => 'sm:col-span-6',
                'rows' => 3,
                'order' => 2,
                'description' => __('Details about this item for your client.', 'easy-invoice'),
            ],
            [
                'name' => 'quantity',
                'type' => 'number',
                'label' => __('Quantity', 'easy-invoice'),
                'placeholder' => '0',
                'required' => true,
                'container_class' => 'sm:col-span-1',
                'min' => '0',
                'step' => '0.01',
                'default_value' => '0',
                'order' => 3,
                'description' => __('How many units of this item are being billed?', 'easy-invoice'),
            ],
            [
                'name' => 'price',
                'type' => 'number',
                'label' => __('Price', 'easy-invoice'),
                'placeholder' => '0.00',
                'required' => true,
                'container_class' => 'sm:col-span-1',
                'min' => '0',
                'step' => '0.01',
                'default_value' => '0.00',
                'order' => 4,
                'description' => __('Unit price for this item.', 'easy-invoice'),
            ]
        ];

        // Add adjust field only if setting allows it
        if (\EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField()) {
            $fields[] = [
                'name' => 'adjust_percentage',
                'type' => 'number',
                'label' => __('Adjust (%)', 'easy-invoice'),
                'placeholder' => '0.00',
                'container_class' => 'sm:col-span-1',
                'min' => '-100',
                'max' => '1000',
                'step' => '0.01',
                'default_value' => '0.00',
                'order' => 5,
                'description' => __('Percentage adjustment to apply to this item (positive for markup, negative for discount).', 'easy-invoice'),
            ];
        }

        // Add total field
        $fields[] = [
            'name' => 'total',
            'type' => 'number',
            'label' => __('Total', 'easy-invoice'),
            'placeholder' => '0.00',
            'container_class' => 'sm:col-span-1',
            'min' => '0',
            'step' => '0.01',
            'default_value' => '0.00',
            'readonly' => true,
            'order' => \EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField() ? 6 : 5,
            'description' => __('Total amount for this item (Quantity x Price) with adjustment applied.', 'easy-invoice'),
        ];

        // Add taxable field
        $fields[] = [
            'name' => 'taxable',
            'type' => 'checkbox',
            'label' => __('Taxable', 'easy-invoice'),
            'container_class' => 'sm:col-span-6',
            'default_value' => '1',
            'order' => \EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField() ? 7 : 6,
            'description' => __('Check if this item is subject to tax.', 'easy-invoice'),
        ];

        return $fields;
    }

    /**
     * Get client options for select field
     *
     * @since 1.0.0
     * @return array
     */
    private function getClientOptions(): array {
        $options = ['' => __('Select a client', 'easy-invoice')];
        
        // Get clients from repository
        $client_repository = new \EasyInvoice\Repositories\ClientRepository();
        $clients = $client_repository->all();
        
        foreach ($clients as $client) {
            $client_name = $client->getBusinessClientName() ?: ($client->getFirstName() . ' ' . $client->getLastName());
            $options[$client->getId()] = $client_name;
        }
        
        return $options;
    }

    /**
     * Get the filter name for tabs
     *
     * @since 1.0.0
     * @return string
     */
    protected function getTabFilterName(): string {
        return 'easy_invoice_invoice_register_tab';
    }

    /**
     * Get the filter name for fields
     *
     * @since 1.0.0
     * @return string
     */
    protected function getFieldFilterName(): string {
        return 'easy_invoice_invoice_register_field';
    }

    /**
     * Get the filter name for templates
     *
     * @since 1.0.0
     * @return string
     */
    protected function getTemplateFilterName(): string {
        return 'easy_invoice_invoice_register_template';
    }

    /**
     * Get the filter name for item fields
     *
     * @since 1.0.0
     * @return string
     */
    protected function getItemFieldFilterName(): string {
        return 'easy_invoice_invoice_register_item_field';
    }
} 