<?php

namespace Daniv04\HaciendaPackage\Providers\Cyberfuel\Transformer;

class CyberfuelTransformer
{

    private static function hasData(mixed $value): bool
    {
        if ($value === null) {
            return false;
        }

        if (is_array($value)) {
            return !empty($value);
        }

        return true;
    }

    public static function transformDocument(array $payload, string $consecutiveNumber, array $dateParsed, string $securityCode): array
    {
        return [
            'api_key' => config('cyberfuel.api_key_stag'),
            'clave' => [
                'sucursal' => $payload['Clave']['Sucursal'] ?? "",
                'terminal' => $payload['Clave']['Terminal'] ?? "",
                'tipo' => $payload['Clave']['TipoComprobante'] ?? "",
                'comprobante' => $consecutiveNumber,
                'pais' => "506",
                'dia' => $dateParsed['day'] ?? "",
                'mes' => $dateParsed['month'] ?? "",
                'anno' => $dateParsed['year'] ?? "",
                'situacion_presentacion' => $payload['Encabezado']['SituacionComprobante'] ?? "1",
                'codigo_seguridad' => $securityCode,
            ],
            'encabezado' => [
                'codigo_actividad' => $payload['Encabezado']['CodigoActividadEmisor'] ?? "",
                'CodigoActividadReceptor' => $payload['Encabezado']['CodigoActividadReceptor'] ?? null,
                'fecha' => $payload['Encabezado']['FechaEmision'] ?? "",
                'condicion_venta' => $payload['Encabezado']['CondicionVenta'] ?? "",
                'CondicionVentaOtros' => $payload['Encabezado']['CondicionVentaOtros'] ?? null,
                'plazo_credito' => $payload['Encabezado']['PlazoCredito'] ?? null,
            ],
            'emisor' => self::tranformSender($payload['Emisor'] ?? []),
            'receptor' => self::transformReceptor($payload['Receptor'] ?? []),
            'detalle' => self::transformDetail($payload['DetalleServicio']['LineaDetalle'] ?? null),
            'otroscargos' => self::transformOthers($payload['OtrosCargos'] ?? null),
            'resumen' => self::transformSummary($payload['ResumenFactura'] ?? []),
            'referencia' => self::transformReference($payload['Referencia'] ?? null),

            'envio' => [
                'logo' => $payload['Envio']['Logo'] ?? "",
                'texto' => $payload['Envio']['Texto'] ?? "",
                'receptor' => [
                    'correo' => $payload['Envio']['Receptor']['CorreoElectronico'] ?? "",
                ],
                'emisor' => [
                    'correo' => $payload['Envio']['Emisor']['CorreoElectronico'] ?? "",
                ]
            ],
            'parametros_documento' => [
                'logo' => $payload['ParametrosDocumento']['Logo'] ?? "",
                'texto' => $payload['ParametrosDocumento']['Texto'] ?? "",
            ],
            'cdp' => [
                'cod_proveedor' => $payload['CDP']['CodigoProveedor'] ?? "",
                'pdf' => $payload['CDP']['Pdf'] ?? "",
            ],

        ];
    }


    public static function tranformSender(array $sender): array
    {
        return [
            'nombre' => $sender['Nombre'] ?? "",
            'identificacion' => self::hasData($sender['Identificacion'] ?? null)
                ? [
                    'tipo' => $sender['Identificacion']['Tipo'] ?? "",
                    'numero' => $sender['Identificacion']['Numero'] ?? "",
                ]
                : null,
            'Registrofiscal8707' => $sender['RegistroFiscal8707'] ?? null,
            'nombre_comercial' => $sender['NombreComercial'] ?? "",
            'ubicacion' => self::hasData($sender['Ubicacion'] ?? null)
                ? [
                    'provincia' => $sender['Ubicacion']['Provincia'] ?? "",
                    'canton' => $sender['Ubicacion']['Canton'] ?? "",
                    'distrito' => $sender['Ubicacion']['Distrito'] ?? "",
                    'barrio' => $sender['Ubicacion']['Barrio'] ?? "",
                    'sennas' => $sender['Ubicacion']['OtrasSenas'] ?? "",
                ]
                : null,
            'OtrasSenasExtranjero' => $sender['OtrasSenasExtranjero'] ?? "",
            'telefono' => self::hasData($sender['Telefono'] ?? null)
                ? [
                    'cod_pais' => $sender['Telefono']['CodigoPais'] ?? "506",
                    'numero' => $sender['Telefono']['NumTelefono'] ?? "",
                ]
                : null,
            'correo_electronico' => self::hasData($sender['CorreoElectronico'] ?? null)
                ? $sender['CorreoElectronico']
                : null,
        ];
    }

    public static function transformReceptor(array $receptor)
    {
        return [
            'nombre' => $receptor['Nombre'] ?? "",
            'identificacion' => self::hasData($receptor['Identificacion'] ?? null)
                ? [
                    'tipo' => $receptor['Identificacion']['Tipo'] ?? "",
                    'numero' => $receptor['Identificacion']['Numero'] ?? "",
                ]
                : null,
            'nombre_comercial' => $receptor['NombreComercial'] ?? "",
            'ubicacion' => self::hasData($receptor['Ubicacion'] ?? null)
                ? [
                    'provincia' => $receptor['Ubicacion']['Provincia'] ?? "",
                    'canton' => $receptor['Ubicacion']['Canton'] ?? "",
                    'distrito' => $receptor['Ubicacion']['Distrito'] ?? "",
                    'barrio' => $receptor['Ubicacion']['Barrio'] ?? "",
                    'sennas' => $receptor['Ubicacion']['OtrasSenas'] ?? "",
                ]
                : null,
            'sennas_extranjero' => $receptor['OtrasSenasExtranjero'] ?? "",
            'telefono' => self::hasData($receptor['Telefono'] ?? null)
                ? [
                    'cod_pais' => $receptor['Telefono']['CodigoPais'] ?? "506",
                    'numero' => $receptor['Telefono']['NumTelefono'] ?? "",
                ]
                : null,
            'correo_electronico' => $receptor['CorreoElectronico'] ?? null,
        ];
    }

    public static function transformDetail(?array $detail): ?array
    {
        if (empty($detail)) {
            return null;
        }

        $detailLines = [];

        foreach ($detail as $details) {
            $detailLines[] = [
                'numero' => $details['NumeroLinea'] ?? "",
                'partida' => $details['PartidaArancelaria'] ?? null,
                'codigo_hacienda' => $details['CodigoCABYS'] ?? "",
                'codigo' => self::transformComercialCode($details['CodigoComercial'] ?? null),
                'cantidad' => $details['Cantidad'] ?? "",
                'unidad_medida' => $details['UnidadMedida'] ?? "",
                'TipoTransaccion' => $details['TipoTransaccion'] ?? null,
                'unidad_medida_comercial' => $details['UnidadMedidaComercial'] ?? null,
                'detalle' => $details['Detalle'] ?? "",
                'NumeroVINoSerie' => $details['NumeroVINoSerie'] ?? null,
                'registromedicamento' => $details['RegistroMedicamento'] ?? null,
                'formafarceutica' => $details['FormaFarmaceutica'] ?? null,
                'DetalleSurtido' => self::transformAssortmentDetail($details['DetalleSurtido'] ?? null),
                'precio_unitario' => $details['PrecioUnitario'] ?? "",
                'monto_total' => $details['MontoTotal'] ?? "",
                'descuento' => self::transformDiscounts($details['Descuento'] ?? null),
                'subtotal' => $details['SubTotal'] ?? "",
                'IVACobradoFabrica' => $details['IVACobradoFabrica'] ?? null,
                'baseimponible' => $details['BaseImponible'] ?? null,
                'impuestos' => self::transformTaxes($details['Impuesto'] ?? [], $details['MontoExportacion'] ?? null),
                'ImpuestoAsumidoEmisorFabrica' => $details['ImpuestoAsumidoEmisorFabrica'] ?? null,
                'impuestoneto' => $details['ImpuestoNeto'] ?? "",
                'montototallinea' => $details['MontoTotalLinea'] ?? "",
            ];
        }

        return $detailLines;
    }

    private static function transformComercialCode(?array $codigos): ?array
    {
        if (empty($codigos)) {
            return null;
        }

        if (isset($codigos['Tipo'])) {
            $codigos = [$codigos];
        }
        $result = [];
        foreach ($codigos as $codigo) {
            $result[] = [
                'tipo' => $codigo['Tipo'] ?? "",
                'numero' => $codigo['Codigo'] ?? "",
            ];
        }

        return $result;
    }

    private static function transformDiscounts(?array $discounts): ?array
    {
        if (empty($discounts)) {
            return null;
        }

        if (isset($discounts['MontoDescuento'])) {
            $discounts = [$discounts];
        }

        $result = [];
        foreach ($discounts as $discount) {
            $result[] = [
                'monto' => $discount['MontoDescuento'] ?? "",
                'CodigoDescuento' => $discount['CodigoDescuento'] ?? "",
                'CodigoDescuentoOTRO' => $discount['CodigoDescuentoOtro'] ?? null,
                'naturaleza' => $discount['NaturalezaDescuento'] ?? null,
            ];
        }

        return $result;
    }

    private static function transformTaxes(array $taxes, ?string $exportAmount): ?array
    {
        if (empty($taxes)) {
            return null;
        }

        $result = [];
        foreach ($taxes as $tax) {
            $result[] = [
                'codigo' => $tax['Codigo'] ?? "",
                'CodigoImpuestoOTRO' => $tax['CodigoImpuestoOTRO'] ?? null,
                'CodigoTarifaIVA' => $tax['CodigoTarifaIVA'] ?? null,
                'tarifa' => $tax['Tarifa'] ?? null,
                'factoriva' => $tax['FactorCalculoIVA'] ?? null,
                'DatosImpuestoEspecifico' => self::hasData($tax['DatosImpuestoEspecifico'] ?? null)
                    ? [
                        'CantidadUnidadMedida' => $tax['DatosImpuestoEspecifico']['CantidadUnidadMedida'] ?? "",
                        'Porcentaje' => $tax['DatosImpuestoEspecifico']['Porcentaje'] ?? null,
                        'Proporcion' => $tax['DatosImpuestoEspecifico']['Proporcion'] ?? null,
                        'VolumenUnidadConsumo' => $tax['DatosImpuestoEspecifico']['VolumenUnidadConsumo'] ?? null,
                        'ImpuestoUnidad' => $tax['DatosImpuestoEspecifico']['ImpuestoUnidad'] ?? null,
                    ]
                    : null,
                'monto' => $tax['Monto'] ?? "",
                'MontoExportacion' => $exportAmount ?? null,
                'exoneracion' => self::hasData($tax['Exoneracion'] ?? null)
                    ? [
                        'tipodocumento' => $tax['Exoneracion']['TipoDocumentoEX1'] ?? "",
                        'TipoDocumentoOTRO' => $tax['Exoneracion']['TipoDocumentoOTRO'] ?? null,
                        'numerodocumento' => $tax['Exoneracion']['NumeroDocumento'] ?? null,
                        'Articulo' => $tax['Exoneracion']['Articulo'] ?? null,
                        'Inciso' => $tax['Exoneracion']['Inciso'] ?? null,
                        'nombreinstitucion' => $tax['Exoneracion']['NombreInstitucion'] ?? "",
                        'NombreInstitucionOtros' => $tax['Exoneracion']['NombreInstitucionOTRO'] ?? null,
                        'fechaemision' => $tax['Exoneracion']['FechaEmisionEX'] ?? "",
                        'TarifaExonerada' => $tax['Exoneracion']['TarifaExonerada'] ?? "",
                        'montoexoneracion' => $tax['Exoneracion']['MontoExoneracion'] ?? "",
                    ]
                    : null,
            ];
        }

        return $result;
    }

    //Assortment details transformation
    private static function transformAssortmentDetail(?array $details): ?array
    {
        if (empty($details)) {
            return null;
        }

        if (isset($details['CodigoCABYSSurtido'])) {
            $details = [$details];
        }

        $result = [];
        foreach ($details as $detail) {
            $result[] = [
                'CodigoCABYSSurtido' => $detail['CodigoCABYSSurtido'] ?? "",
                'CodigoComercialSurtido' => self::transformComercialCodeAssortment($detail['CodigoComercialSurtido'] ?? []),
                'CantidadSurtido' => $detail['CantidadSurtido'] ?? "",
                'UnidadMedidaSurtido' => $detail['UnidadMedidaSurtido'] ?? "",
                'UnidadMedidaComercialSurtido' => $detail['UnidadMedidaComercialSurtido'] ?? "",
                'DetalleSurtido' => $detail['DetalleSurtido'] ?? "",
                'PrecioUnitarioSurtido' => $detail['PrecioUnitarioSurtido'] ?? "",
                'MontoTotalSurtido' => $detail['MontoTotalSurtido'] ?? "",
                'DescuentoSurtido' => self::transformDiscountAssortment($detail['DescuentoSurtido'] ?? []),
                'SubTotalSurtido' => $detail['SubTotalSurtido'] ?? "",
                'IVACobradoFabricaSurtido' => $detail['IVACobradoFabricaSurtido'] ?? "",
                'BaseImponibleSurtido' => $detail['BaseImponibleSurtido'] ?? "",
                'ImpuestoSurtido' => self::transformTaxAssortment($detail['ImpuestoSurtido'] ?? []),
            ];
        }

        return $result;
    }

    private static function transformComercialCodeAssortment(array $codigos): array
    {
        if (empty($codigos)) {
            return [];
        }

        // Si es un solo código (array asociativo), convertirlo a array
        if (isset($codigos['TipoSurtido'])) {
            $codigos = [$codigos];
        }

        $result = [];
        foreach ($codigos as $codigo) {
            $result[] = [
                'TipoSurtido' => $codigo['TipoSurtido'] ?? "",
                'CodigoSurtido' => $codigo['CodigoSurtido'] ?? "",
            ];
        }

        return $result;
    }

    private static function transformDiscountAssortment(array $descuentos): array
    {
        if (empty($descuentos)) {
            return [];
        }

        // Si es un solo descuento (array asociativo), convertirlo a array
        if (isset($descuentos['MontoDescuentoSurtido'])) {
            $descuentos = [$descuentos];
        }

        $result = [];
        foreach ($descuentos as $descuento) {
            $result[] = [
                'MontoDescuentoSurtido' => $descuento['MontoDescuentoSurtido'] ?? "",
                'CodigoDescuentoSurtido' => $descuento['CodigoDescuentoSurtido'] ?? "",
                'DescuentoSurtidoOtros' => $descuento['DescuentoSurtidoOtros'] ?? "",
            ];
        }

        return $result;
    }

    private static function transformTaxAssortment(array $impuestos): array
    {
        if (empty($impuestos)) {
            return [];
        }

        // Si es un solo impuesto (array asociativo), convertirlo a array
        if (isset($impuestos['CodigoImpuestoSurtido'])) {
            $impuestos = [$impuestos];
        }

        $result = [];
        foreach ($impuestos as $impuesto) {
            $result[] = [
                'CodigoImpuestoSurtido' => $impuesto['CodigoImpuestoSurtido'] ?? "",
                'CodigoImpuestoOTROSurtido' => $impuesto['CodigoImpuestoOTROSurtido'] ?? "",
                'CodigoTarifaIVASurtido' => $impuesto['CodigoTarifaIVASurtido'] ?? "",
                'TarifaSurtido' => $impuesto['TarifaSurtido'] ?? "",
                'DatosImpuestoEspecificoSurtido' => self::hasData($impuesto['DatosImpuestoEspecificoSurtido'] ?? null)
                    ? [
                        'CantidadUnidadMedidaSurtido' => $impuesto['DatosImpuestoEspecificoSurtido']['CantidadUnidadMedidaSurtido'] ?? "",
                        'PorcentajeSurtido' => $impuesto['DatosImpuestoEspecificoSurtido']['PorcentajeSurtido'] ?? "",
                        'ProporcionSurtido' => $impuesto['DatosImpuestoEspecificoSurtido']['ProporcionSurtido'] ?? "",
                        'VolumenUnidadConsumoSurtido' => $impuesto['DatosImpuestoEspecificoSurtido']['VolumenUnidadConsumoSurtido'] ?? "",
                        'ImpuestoUnidadSurtido' => $impuesto['DatosImpuestoEspecificoSurtido']['ImpuestoUnidadSurtido'] ?? "",
                    ]
                    : null,
                'MontoImpuestoSurtido' => $impuesto['MontoImpuestoSurtido'] ?? "",
            ];
        }

        return $result;
    }


    public static function  transformOthers(?array $otherCharges): ?array
    {
        if (empty($otherCharges)) {
            return null;
        }

        $result = [];
        foreach ($otherCharges as $charge) {
            $result[] = [
                [
                    'tipodocumento' => $charge['TipoDocumentoOC'] ?? "",
                    'TipoDocumentoOTROS' => $charge['TipoDocumentoOTROS'] ?? null,
                    'IdentificacionTercero' => self::hasData($charge['IdentificacionTercero'] ?? null)
                        ? [
                            'tipo' => $charge['IdentificacionTercero']['Tipo'] ?? "",
                            'numero' => $charge['IdentificacionTercero']['Numero'] ?? "",
                        ]
                        : null,
                    'nombre' => $charge['NombreTercero'] ?? null,
                    'detalle' => $charge['Detalle'] ?? "",
                    'porcentaje' => $charge['PorcentajeOC'] ?? null,
                    'montocargo' => $charge['MontoCargo'] ?? "",
                ],
            ];
        }
        return $result;
    }


    public static function transformSummary(array $summary): array
    {
        return [
            'moneda' => $summary['CodigoTipoMoneda']['CodigoMoneda'] ?? "CRC",
            'tipo_cambio' => $summary['CodigoTipoMoneda']['TipoCambio'] ?? "1.00000",
            'totalserviciogravado' => $summary['TotalServGravados'] ?? "0.00000",
            'totalservicioexento' => $summary['TotalServExentos'] ?? "0.00000",
            'totalservicioexonerado' => $summary['TotalServExonerado'] ?? "0.00000",
            'TotalServNoSujeto' => $summary['TotalServNoSujeto'] ?? "0.00000",
            'totalmercaderiagravado' => $summary['TotalMercanciasGravadas'] ?? "0.00000",
            'totalmercaderiaexento' => $summary['TotalMercanciasExentas'] ?? "0.00000",
            'totalmercaderiaexonerado' => $summary['TotalMercExonerada'] ?? "0.00000",
            'TotalMercNoSujeta' => $summary['TotalMercNoSujeta'] ?? "0.00000",
            'totalgravado' => $summary['TotalGravado'] ?? "0.00000",
            'totalexento' => $summary['TotalExento'] ?? "0.00000",
            'totalexonerado' => $summary['TotalExonerado'] ?? "0.00000",
            'TotalNoSujeto' => $summary['TotalNoSujeto'] ?? "0.00000",
            'totalventa' => $summary['TotalVenta'] ?? "",
            'totaldescuentos' => $summary['TotalDescuentos'] ?? "0.00000",
            'totalventaneta' => $summary['TotalVentaNeta'] ?? "",
            'TotalDesgloseImpuesto' => self::totalTaxBreakdown($summary['TotalDesgloseImpuesto'] ?? []),
            'totalimpuestos' => $summary['TotalImpuesto'] ?? "0.00000",
            'TotalImpAsumEmisorFabrica' => $summary['TotalImpAsumEmisorFabrica'] ?? "0.00000",
            'totalivadevuelto' => $summary['TotalIVADevuelto'] ?? "0.00000",
            'totalotroscargos' => $summary['TotalOtrosCargos'] ?? "0.00000",
            'MedioPago' => self::transformPaymentMeans($summary['MedioPago'] ?? []),
            'totalcomprobante' => $summary['TotalComprobante'] ?? "",
        ];
    }

    public static function totalTaxBreakdown(array $taxBreakdown): ?array
    {
        if (empty($taxBreakdown)) {
            return null;
        }
        $result = [];
        foreach ($taxBreakdown as $tax) {
            $result[] = [
                'Codigo' => $tax['Codigo'] ?? "",
                'CodigoTarifaIVA' => $tax['CodigoTarifaIVA'] ?? null,
                'TotalMontoImpuesto' => $tax['TotalMontoImpuesto'] ?? "",
            ];
        }
        return $result;
    }

    public static function transformPaymentMeans(array $paymentMeans): ?array
    {
        if (empty($paymentMeans)) {
            return null;
        }

        $result = [];
        foreach ($paymentMeans as $medioPago) {
            $result[] = [
                'TipoMedioPago' => $medioPago['TipoMedioPago'] ?? "",
                'MedioPagoOtros' => $medioPago['MedioPagoOtros'] ?? null,
                'TotalMedioPago' => $medioPago['TotalMedioPago'] ?? "",
            ];
        }
        return $result;
    }


    public static function transformReference(?array $reference): ?array
    {

        if (empty($reference)) {
            return null;
        }
        $result = [];
        foreach ($reference as $ref) {
            $result[] = [
                'TipoDocIR' => $ref['TipoDocIR'] ?? "",
                'TipoDocRefOTRO' => $ref['TipoDocRefOTRO'] ?? null,
                'numero_documento' => $ref['Numero'] ?? "",
                'fecha_emision' => $ref['FechaEmisionIR'] ?? "",
                'codigo' => $ref['Codigo'] ?? null,
                'CodigoReferenciaOTRO' => $ref['CodigoReferenciaOTRO'] ?? null,
                'razon' => $ref['Razon'] ?? null,
            ];
        }
        return $result;
    }




    public static function transformSentDocument(array $payload, string $consecutiveNumber, array $dateParsed, string $securityCode): array
    {
        return [
            'api_key' => config('cyberfuel.api_key_stag'),
            'clave' => [
                'sucursal' => $payload['Clave']['Sucursal'] ?? "",
                'terminal' => $payload['Clave']['Terminal'] ?? "",
                'tipo' => $payload['Clave']['TipoComprobante'] ?? "",
                'comprobante' => $consecutiveNumber,
                'pais' => "506",
                'dia' => $dateParsed['day'] ?? "",
                'mes' => $dateParsed['month'] ?? "",
                'anno' => $dateParsed['year'] ?? "",
                'situacion_presentacion' => $payload['Clave']['SituacionComprobante'] ?? "1",
                'codigo_seguridad' => $securityCode,
            ],
            'emisor' => [
                'nombre' => $payload['Emisor']['Nombre'] ?? "",
                'identificacion' => [
                    'tipo' => $payload['Emisor']['Identificacion']['Tipo'] ?? "",
                    'numero' => $payload['Emisor']['Identificacion']['Numero'] ?? "",
                ]
            ],
            'proveedor' =>[
                'nombre' => $payload['Receptor']['Nombre'] ?? "",
                'identificacion' => [
                    'tipo' => $payload['Receptor']['Identificacion']['Tipo'] ?? "",
                    'numero' => $payload['Receptor']['Identificacion']['Numero'] ?? "",
                ]
            ],
            'detalle' =>[
                'Clave' => $payload['Detalle']['Clave'],
                'FechaEmisionDoc' => $payload['FechaEmision'],
                'Mensaje' => $payload['Detalle']['CodigoMensaje'],
                'DetalleMensaje'=> $payload['Detalle']['Mensaje'] ?? null,
                'CodigoActividad' => $payload['Detalle']['CodigoActividad'] ?? null,
                'CondicionImpuesto' => $payload['Detalle']['CondicionImpuesto'] ?? null,
                'MontoTotalImpuestoAcreditar' => $payload['Detalle']['MontoTotalImpuestoAcreditar'] ?? null,
                'MontoTotalDeGastoAplicable' => $payload['Detalle']['MontoTotalDeGastoAplicable'] ?? null,
                'MontoTotalImpuesto' => $payload['Detalle']['MontoTotalImpuesto'] ?? null,
                'TotalFactura' => $payload['Detalle']['TotalFactura'] ,
            ]
        ];
    }
}
