<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

use App\Enums\Invoicing\InvoiceStatus;
use App\Enums\Invoicing\InvoiceCancellationStatus;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('tax_invoices', function (Blueprint $table) {
            $table->id();

              //* IDENTIDAD Y RELACIONES
                $table->nullableMorphs('system_service'); // (Relación polimórfica opcional) Origen transaccional de la Factura. Invoices -> Reservations|ExternalReservations|Orders.

                $table->unsignedBigInteger('substitution_invoice_id')->nullable(); // Factura Original/Sustituida (util cuando se emite un CFDI para sustituir otro por X motivo relevante).
                $table->foreign('substitution_invoice_id')
                    ->references('id')
                    ->on('tax_invoices')
                    ->nullOnDelete(); // Si la original desaparece, se limpia la referencia.

                $table->unsignedBigInteger('tax_format_id')->nullable(); // Formato visual/render (plantilla de PDF) asociado a la factura.
                $table->foreign('tax_format_id')
                    ->references('id')
                    ->on('tax_formats')
                    ->nullOnDelete();

                $table->unsignedBigInteger('tax_branch_id')->nullable(); // Sucursal emisora de la factura.
                $table->foreign('tax_branch_id')
                    ->references('id')
                    ->on('tax_branches')
                    ->nullOnDelete();

                $table->unsignedBigInteger('client_id'); // Receptor de la factura (cliente).
                $table->foreign('client_id')
                    ->references('id')
                    ->on('clients')
                    ->cascadeOnDelete();

              //* ENCABEZADO CFDI
                $table->char('cfdi_use', 4)->nullable();                // Uso del CFDI (SAT)
                $table->char('invoice_type', 1)->nullable();            // Tipo de comprobante (SAT).
                $table->char('payment_form', 3)->nullable();            // Forma de pago (SAT).
                $table->char('payment_method', 3)->nullable();          // Método/Modo de pago (SAT).
                $table->char('currency', 3)->nullable();                // Moneda ISO 4217 (SAT).
                $table->char('export', 2)->nullable();                  // Tipo de Exportación (SAT).
                $table->datetime('date');                               // Fecha de emisión del CFDI/timbrado (Es un valor local, por lo que puede diferir de la fecha fiscal).
                $table->datetime('certification_date')->nullable();     // Fecha de certificación del CFDI/timbrado.

              //* IDENTIFICADORES DE TIMBRADO
                $table->unsignedBigInteger('serial_consecutive')->nullable();           // Consecutivo de Serie (ID de control interno de formatos)
                $table->string('facturapi_invoice_id', 64)->unique()->nullable();       // UUID de facturapi para la Factura
                $table->uuid('sat_uuid')->unique()->nullable();                         // UUID fiscal (Timbre SAT, TFD). Sólo se llena una vez timbrado exitosamente.
                $table->char('cancel_motive', 2)->nullable();                           // Motivo de cancelación (SAT).

                $table->longText('cfdi_seal')->nullable();                              // Sello del comprobante (emisor)
                $table->longText('sat_seal')->nullable();                               // Sello del SAT (Timbre)
                $table->string('sat_cert_number')->nullable();                          // No de Certificado de SAT
                $table->longText('tfd_original_string')->nullable();                    // Cadena original del TFD

              //* CONDICIONES DE PAGO Y CRÉDITO
                $table->integer('credit_days')->nullable();         // Días de crédito pactados (Unicamente para Factura a Crédito - PPD).
                $table->date('due_date')->nullable();               // Fecha límite de pago, vencimiento del crédito (Unicamente para Factura a Crédito - PPD).
                $table->string('notes')->default('Ninguna');        // Notas internas o visibles en PDF (términos, indicaciones al cliente, etc.).
                $table->json('global')->nullable();                 // Aspectos globales de la Factura (Solo en facturas globales - publico en general)
                $table->json('related_documents')->nullable();      // Documentos Fiscales relacionados a la Factura
                $table->text('verification_url')->nullable();       // URL de verificación del SAT (base del QR).

              //* IMPORTES, IMPUESTOS Y TOTALES
                $table->json('local_taxes')->nullable();                // Impuestos locales/estatales.
                $table->decimal('subtotal', 12, 2)->nullable();         // Suma de importes de conceptos sin impuestos (antes de traslados/retenciones).
                $table->decimal('taxes_total', 12, 2)->nullable();      // Total de impuestos netos (traslados - retenciones) a nivel factura.
                $table->decimal('local_taxes_total', 12, 2)->nullable();// Total de impuestos locales netos (traslados - retenciones) a nivel factura.
                $table->decimal('total', 12, 2)->nullable();            // Importe total (subtotal +/- impuestos + locales si aplican).
                $table->decimal('exchange_rate', 14, 6)->nullable();    // Tipo de Cambio (valor de conversión entre la moneda extranjera y el peso mexicano).

              //* ESTATUS Y CICLO DE VIDA (LOCALES)
                $table->enum('status', array_column(InvoiceStatus::cases(), 'value'))
                    ->default(InvoiceStatus::Draft->value);  // Estado interno del documento.

                $table->enum('cancellation_status', array_column(InvoiceCancellationStatus::cases(), 'value'))
                    ->default(InvoiceCancellationStatus::None->value); // Flujo de cancelación SAT (acuse).

              //* ARTEFACTOS / RECURSOS (DESCARGAS Y RUTAS)
                $table->text('xml_path')->nullable();   // Ruta/URL de almacenamiento local del XML.

              //* CONTROL DE RESPUESTAS
                $table->json('request_payload')->nullable();        // Último payload enviado al proveedor (para auditoría/soporte).
                $table->json('response_payload')->nullable();       // Última respuesta recibida del proveedor (incluye timbre, errores, links, etc.).
                $table->json('last_error_returned')->nullable();    // Último error (normalizado o crudo) devuelto por el proveedor o validaciones.

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('tax_invoices');
    }
};
