<?php

namespace App\Http\Requests\Invoicing;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

use App\Rules\Invoicing\MoralTaxIdentifier;
use App\Rules\SAT\ValidInvoiceDate;
use App\Rules\SAT\ValidSatCode;

use App\Enums\Invoicing\QuantityApplicationType;

class InvoiceIssueRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        // Variables de Control
        $quantityTypes   = array_map(fn($c) => $c->value, QuantityApplicationType::cases());
        $taxApplications = ['tr', 'rt']; // Catálogo interno (traslado/retención)
        $country         = session('country', 'MEX');

        // Inputs Condicionales
        $invoiceType   = $this->input('invoice_type');
        $currency      = $this->input('currency', 'MXN');
        $paymentMethod = $this->input('payment_method');

        // Control Values
        $type_export_required = ['I', 'E'];
        $type_payment_required = ['I', 'E', 'N'];

        return [
          // Encabezado
            'tax_branch_id' => ['required','integer','exists:tax_branches,id'],
            'date'          => ['required', 'date', new ValidInvoiceDate()],
            'invoice_type'  => ['required', new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_TipoDeComprobante'] )],
            'currency'      => ['required', new ValidSatCode(table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_Moneda'])],
            'notes'         => ['nullable', 'string', 'max:500'],

            'export'        => [
                Rule::requiredIf(fn () => in_array($invoiceType, $type_export_required)),
                new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_Exportacion'])
            ],
            'exchange_rate' => [
                Rule::requiredIf(fn () => $currency !== 'MXN'),
                'numeric', 'min:0.000001',
            ],
            'payment_method'=> [
                Rule::requiredIf(fn () => in_array($invoiceType, $type_payment_required)),
                new ValidSatCode(table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_MetodoPago']),
            ],
            'payment_form'  => [
                Rule::requiredIf(fn () => in_array($invoiceType, $type_payment_required) && $paymentMethod !== 'PPD'),
                new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_FormaPago'] )
            ],

          // Conceptos
            'items_summary'                     => ['required', 'array', 'min:1'],
            'items_summary.*.line_number'       => ['nullable', 'integer', 'min:1'],
            'items_summary.*.name'              => ['required', 'string', 'min:1', 'max:150'],
            'items_summary.*.prod_serv_id'      => ['nullable', 'integer', 'exists:tax_prod_servs,id'],
            'items_summary.*.prod_serv_key'     => ['required', 'string', new ValidSatCode(table: 'catalog_prod_serv', column: 'prod_serv_key')],
            'items_summary.*.sat_description'   => ['required', 'string', 'max:250'],
            'items_summary.*.object_tax'        => ['required', new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_ObjetoImp', ['item_key','in',['01','02']]] )],
            'items_summary.*.unit_key'          => ['required', 'string', new ValidSatCode( table: 'catalog_units', column: 'unit_key' )],
            'items_summary.*.unit_price'        => ['required', 'numeric', 'min:0'],
            'items_summary.*.quantity'          => ['required', 'numeric', 'min:0'],
            'items_summary.*.subtotal'          => ['required', 'numeric', 'min:0'],
            'items_summary.*.discount_type'     => ['required', Rule::in($quantityTypes)],
            'items_summary.*.discount_value'    => ['required', 'numeric', 'min:0'],
            'items_summary.*.discount_total'    => ['required', 'numeric', 'min:0'],
            'items_summary.*.description'       => ['required', 'string', 'max:1000'],
            'items_summary.*.total'             => ['required', 'numeric', 'min:0'],

            'items_summary.*.taxes'                     => ['nullable', 'array'],
            'items_summary.*.taxes.*.tax'               => ['required_with:items_summary.*.taxes', new ValidSatCode(table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_Impuesto'])],
            'items_summary.*.taxes.*.tax_application'   => ['required_with:items_summary.*.taxes', Rule::in($taxApplications)],
            'items_summary.*.taxes.*.rate_quote'        => ['required_with:items_summary.*.taxes', 'numeric', 'min:0'],
            'items_summary.*.taxes.*.charges'           => ['required_with:items_summary.*.taxes', 'numeric', 'min:0'],

            'items_summary.*.local_taxes'                     => ['nullable','array'],
            'items_summary.*.local_taxes.*.name'              => ['required_with:items_summary.*.local_taxes','string','max:150'],
            'items_summary.*.local_taxes.*.tax_application'   => ['required_with:items_summary.*.local_taxes', Rule::in($taxApplications)],
            'items_summary.*.local_taxes.*.rate_quote'        => ['required_with:items_summary.*.local_taxes','numeric','min:0'],
            'items_summary.*.local_taxes.*.charges'           => ['required_with:items_summary.*.local_taxes','numeric','min:0'],

            'items_summary.*.property_tax_account'           => ['nullable','string','max:50', 'regex:/^[A-Za-z0-9\s\-\/\.]+$/u'],

          // Tercero en cuenta
            'items_summary.*.third_account_data'                => ['nullable', 'array'],
            'items_summary.*.third_account_data.tax_identifier' => ['nullable', new MoralTaxIdentifier($country)],
            'items_summary.*.third_account_data.legal_name'     => ['nullable', 'string', 'max:255'],
            'items_summary.*.third_account_data.tax_system'     => ['nullable', new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_RegimenFiscal'] )],
            'items_summary.*.third_account_data.zip'            => ['nullable', 'string', 'max:10'],

          // Totales factura
            'subtotal'  => ['required', 'numeric', 'min:0'],
            'total'     => ['required', 'numeric', 'min:0'],

          // Documentos Adicionales
            'additional_docs'                 => ['nullable', 'array'],
            'additional_docs.*.uuid'          => ['required_with:additional_docs', 'uuid'],
            'additional_docs.*.relation_type' => ['required_with:additional_docs', new ValidSatCode( table: 'catalog_items', column: 'item_key', wheres: ['catalog_code' => 'c_TipoDeRelaciones'] )],
            'additional_docs.*.description'   => ['nullable', 'string', 'max:255'],

          // Formato interno de impresión/timbrado
            'tax_format_id' => ['nullable', 'integer', 'exists:tax_formats,id'],

          // Control de Crédito
            'credit_days' => [
                // Rule::requiredIf(fn () => $paymentMethod === 'PPD'),
                'nullable', 'integer','min:1','max:365'
            ],
            'due_date'    => [
                // Rule::requiredIf(fn () => $paymentMethod === 'PPD'),
                'nullable', 'date','after_or_equal:date'
            ],
        ];
    }
}
