<?php

require_once('public/lib/print/num_letras.php');
class PseModel extends Model
{

    public function __construct()
    {
        parent::__construct();
    }



    public function getDataComprobante($id_venta)
    {

        $comprobante = $this->getDataDocumento($id_venta);

        if ($comprobante === null) {

            return;
        }

        $empresa = $this->getDataEmpresa();
        $cliente = $this->getDataCliente($comprobante['id_cliente']);


        $data = [

            "token_cliente" => "FACTURALAYA_BZ1GPEX6RJ21EKIRAM56",
            "ruc_proveedor" => "10470949444",
            "secret_data" => [
                "tipo_certificado" => "pse_facturalaya",
                "tipo_proceso" => "prueba",
            ],
            "emisor" => [
                "ruc" => $empresa['ruc'],
                "tipo_doc" => "6",
                "email" => "aquino.alex@gmail.com",
                "nom_comercial" => $empresa['nombre_comercial'],
                "razon_social" => $empresa['razon_social'],
                "codigo_ubigeo" => $empresa['ubigeo'],
                "direccion" => $empresa['direccion_fiscal'],
                "modalidad_envio_sunat" => "inmediato",
                "direccion_departamento" => $empresa['departamento'],
                "direccion_provincia" => $empresa['provincia'],
                "direccion_distrito" => $empresa['distrito'],
                "direccion_codigopais" => "PE",
            ],
            "cliente_tipodocumento" => "6",
            "cliente_numerodocumento" => $cliente['ruc'],
            "cliente_nombre" => $cliente['razon_social'],
            "cliente_direccion" => $cliente['direccion'],
            "cliente_pais" => "PE",
            "cliente_ciudad" => "Huancayo",
            "cliente_codigoubigeo" => "1212",
            "cliente_departamento" => "",
            "cliente_provincia" => "",
            "cliente_distrito" => "",
            "detalle" => $comprobante['detalle'],
            "tipo_operacion" => "0101",
            "total_gravadas" => 0.00,
            "total_inafecta" => 0.00,
            "total_exoneradas" => $comprobante['total'],
            "total_gratuitas" => 0.00,
            "total_exportacion" => 0.00,
            "total_isc" => 0.00,
            "total_icbper" => 0.00,
            "total_otr_imp" => 0.00,
            "total_descuento" => 0.00,
            "impuesto_icbper" => 0.00,
            "porcentaje_igv" => 18.00,
            "total_igv" => 0.00,
            "sub_total" => $comprobante['total'],
            "total" => $comprobante['total'],
            "total_letras" => numtoletras($comprobante['total']),
            "docs_referencia" => [],
            "nro_otr_comprobante" => "",
            "transporte_nro_placa" => "",
            "cod_moneda" => "PEN",
            "cod_sucursal_sunat" => "0000",
            "fecha_comprobante" => substr($comprobante['fecha_venta'], 0, 10),
            "fecha_vto_comprobante" => substr($comprobante['fecha_venta'], 0, 10),
            "forma_de_pago" => "contado",
            "monto_deuda_total" => 0.00,
            "detalle_cuotas" => [],
            "cod_tipo_documento" => $this->codigoDocumentoPorNumero((int) $comprobante['id_tipo_doc']),
            "serie_comprobante" => $comprobante['serie_doc'],
            "numero_comprobante" => (int) $comprobante['nro_doc'],
        ];

        return $data;

    }


    private function codigoDocumentoPorNumero(int $n): ?string
    {
        static $map = [
        1 => '03',
        2 => '01',
        3 => '77'
        ];
        return $map[$n] ?? null; // null si no existe
    }


    public function getDataCliente(int $id_cliente): ?array
    {
        try {
            $sql = "SELECT * FROM tm_cliente WHERE id_cliente = :id LIMIT 1";
            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':id', $id_cliente, \PDO::PARAM_INT);
            $stmt->execute();

            $row = $stmt->fetch(\PDO::FETCH_ASSOC);
            return $row ?: null;
        } catch (\Throwable $th) {
            throw $th;
        }
    }

    public function getDataEmpresa(): ?array
    {
        try {
            // Si solo tienes 1 registro de empresa, usa LIMIT 1
            $sql = "SELECT * FROM tm_empresa LIMIT 1";
            $stmt = $this->db->query($sql);
            $row = $stmt->fetch(\PDO::FETCH_ASSOC);
            return $row ?: null;
        } catch (\Throwable $th) {
            throw $th;
        }
    }

    // public function getDataDocumento(int $id_venta): ?array
    // {
    //     try {
    //         $sql = "SELECT * FROM tm_venta WHERE id_venta = :id LIMIT 1";
    //         $stmt = $this->db->prepare($sql);
    //         $stmt->bindValue(':id', $id_venta, \PDO::PARAM_INT);
    //         $stmt->execute();

    //         $row = $stmt->fetch(\PDO::FETCH_ASSOC);
    //         return $row ?: null; // null si no hay registro
    //     } catch (\Throwable $th) {
    //         // Loguea y relanza; evita die()
    //         throw $th;
    //     }
    // }

    public function getDataDocumento(int $id_venta): ?array
    {
        try {

            $sql = "SELECT * FROM tm_venta WHERE id_venta = :id LIMIT 1";
            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':id', $id_venta, \PDO::PARAM_INT);
            $stmt->execute();

            $venta = $stmt->fetch(\PDO::FETCH_ASSOC);
            if (!$venta) {
                return null;
            }


            $igvPercent = 0;
            $igvRate = $igvPercent / 100.0;


            $sqlDet = "
            SELECT
                d.id_pres,
                pp.cod_prod,
                SUM(d.cant)                               AS cantidad_total,
                SUM(d.cant * d.precio)                    AS total,
                'NIU'                                           AS unidad_medida,
                COALESCE(MAX(pp.cod_prod), '')                  AS codigo_det,
                COALESCE(MAX(pp.presentacion), '')            AS presentacion
            FROM tm_detalle_pedido d
            INNER JOIN tm_producto_pres pp ON pp.id_pres = d.id_pres
            WHERE d.id_pedido = :id_ref
            GROUP BY d.id_pres
            ORDER BY MIN(d.id_pres) ASC
        ";

            $stDet = $this->db->prepare($sqlDet);
            $stDet->execute(['id_ref' => (int) $venta['id_pedido']]);
            $rows = $stDet->fetchAll(\PDO::FETCH_ASSOC) ?: [];

            $detalle = [];
            $item = 1;

            foreach ($rows as $r) {
                $cant = (float) $r['cantidad_total'];
                $importeCon = (float) $r['total'];                 // total con IGV
                $precioCon = $cant > 0 ? round($importeCon / $cant, 2) : 0.0;                 // unitario con IGV
                $precioSin = round($precioCon / (1 + $igvRate), 2);                              // unitario sin IGV
                $importeSin = round($importeCon / (1 + $igvRate), 2);                             // total sin IGV
                $igvDet = round($importeCon - $importeSin, 2);

                $desc = trim(($r['presentacion'] ?? ''));

                $detalle[] = [
                    "ITEM_DET" => (string) $item++,
                    "UNIDAD_MEDIDA_DET" => $r['unidad_medida'] ?: 'NIU',
                    "PRECIO_TIPO_CODIGO" => "01",
                    "COD_TIPO_OPERACION_DET" => "20",
                    "CANTIDAD_DET" => $cant,
                    "PRECIO_DET" => $precioCon,      // unitario CON IGV
                    "IGV_DET" => $igvDet,         // IGV total del ítem
                    "ICBPER_DET" => 0,
                    "ISC_DET" => 0,
                    "PRECIO_SIN_IGV_DET" => $precioSin,      // unitario SIN IGV
                    "IMPORTE_DET" => round($importeCon, 2), // total CON IGV
                    "CODIGO_DET" => $r['codigo_det'],
                    "DESCRIPCION_DET" => $desc,
                    "DESCUENTO_ITEM" => "no",
                    "PORCENTAJE_DESCUENTO" => 0,
                    "MONTO_DESCUENTO" => 0,
                    "CODIGO_DESCUENTO" => "00",
                ];
            }

            $venta['detalle'] = $detalle;

            return $venta;

        } catch (\Throwable $th) {
            throw $th;
        }
    }

    public function setDataDocumento(
        int $id_venta,
        int $enviado_sunat,
        ?string $code_respuesta_sunat,
        ?string $descripcion_sunat_cdr,
        ?string $name_file_sunat,
        ?string $hash_cdr,
        ?string $hash_cpe
    ): bool {
        try {
            $sql = "UPDATE tm_venta
                   SET enviado_sunat         = :enviado_sunat,
                       code_respuesta_sunat  = :code_respuesta_sunat,
                       descripcion_sunat_cdr = :descripcion_sunat_cdr,
                       name_file_sunat       = :name_file_sunat,
                       hash_cdr              = :hash_cdr,
                       hash_cpe              = :hash_cpe
                 WHERE id_venta = :id_venta";

            $stmt = $this->db->prepare($sql);
            $ok = $stmt->execute([
                ':enviado_sunat' => $enviado_sunat,
                ':code_respuesta_sunat' => $code_respuesta_sunat,
                ':descripcion_sunat_cdr' => $descripcion_sunat_cdr,
                ':name_file_sunat' => $name_file_sunat,
                ':hash_cdr' => $hash_cdr,
                ':hash_cpe' => $hash_cpe,
                ':id_venta' => $id_venta,
            ]);

            // rowCount puede ser 0 si los valores son iguales; igual consideramos éxito si ejecutó.
            return $ok && $stmt->rowCount() >= 0;
        } catch (\Throwable $th) {
            throw $th;
        }
    }


}