<?php
declare(strict_types=1);

namespace App\Services;

use DateTimeInterface;

class HaciendaConsecutivo
{
    /**
     * Genera el número consecutivo de 20 dígitos:
     * A: 1-3  = sucursal (3 dígitos)
     * B: 4-8  = terminal (5 dígitos)
     * C: 9-10 = tipo comprobante (01=FE, 02=ND, 03=NC, 04=TE, etc.)
     * D: 11-20= secuencia (10 dígitos)
     */
    public static function generarNumeroConsecutivo(
        int $sucursal,
        int $terminal,
        string $tipoDocumento,
        int $secuencia
    ): string {
        $codigoTipo = self::mapTipoDocumento($tipoDocumento);

        $sucursalStr  = str_pad((string)$sucursal, 3, '0', STR_PAD_LEFT);
        $terminalStr  = str_pad((string)$terminal, 5, '0', STR_PAD_LEFT);
        $secuenciaStr = str_pad((string)$secuencia, 10, '0', STR_PAD_LEFT);

        return $sucursalStr . $terminalStr . $codigoTipo . $secuenciaStr;
    }

    /**
     * Genera la clave numérica de 50 dígitos:
     *  - 3  = país (506)
     *  - 2  = día
     *  - 2  = mes
     *  - 2  = año (dos dígitos)
     *  - 12 = identificación emisor
     *  - 20 = número consecutivo
     *  - 1  = situación (1=normal, 2=contingencia, 3=sin internet)
     *  - 8  = código de seguridad
     */
    public static function generarClave(
        DateTimeInterface $fecha,
        string $identificacionEmisor,
        string $numeroConsecutivo,
        string $situacion = '1',
        ?int $codigoSeguridad = null
    ): string {
        // País fijo Costa Rica
        $codigoPais = '506';

        $dia = $fecha->format('d'); // 2 dígitos
        $mes = $fecha->format('m'); // 2 dígitos
        $anio = $fecha->format('y'); // 2 dígitos

        // Dejar solo números y ajustar a 12 dígitos
        $soloNumeros = preg_replace('/\D+/', '', $identificacionEmisor) ?? '';
        $soloNumeros = substr($soloNumeros, -12); // últimos 12
        $ident12 = str_pad($soloNumeros, 12, '0', STR_PAD_LEFT);

        // Código de seguridad
        if ($codigoSeguridad === null) {
            $codigoSeguridad = random_int(0, 99999999);
        }
        $seguridadStr = str_pad((string)$codigoSeguridad, 8, '0', STR_PAD_LEFT);

        // Situación debe ser 1 carácter
        if ($situacion === '' || strlen($situacion) !== 1) {
            $situacion = '1';
        }

        return $codigoPais
            . $dia
            . $mes
            . $anio
            . $ident12
            . $numeroConsecutivo
            . $situacion
            . $seguridadStr;
    }

    /**
     * Mapea FE/NC/ND/TE → código Hacienda de 2 dígitos.
     */
    private static function mapTipoDocumento(string $tipo): string
    {
        $tipo = strtoupper(trim($tipo));

        return match ($tipo) {
            'FE' => '01', // Factura electrónica
            'ND' => '02', // Nota débito
            'NC' => '03', // Nota crédito
            'TE' => '04', // Tiquete electrónico
            'FEC' => '08', // Factura electrónica de compra
            'FEE' => '09', // Factura electrónica exportación (si la usas)
            default => '99', // Otros / fallback
        };
    }
}
