<?php
namespace FacturaScripts\Plugins\AgentesComerciales;

use FacturaScripts\Core\Template\CronClass;
use FacturaScripts\Core\Base\DataBase\DataBaseWhere;

class Cron extends CronClass
{
    public function run(): void
    {
        $this->procesarFacturas();
    }

    private function procesarFacturas(): void
    {
        $facturaModel = new \FacturaScripts\Dinamic\Model\FacturaCliente();
        $fechaLimite = date('Y-m-d', strtotime('-1 day'));
        
        $sql = "SELECT idfactura FROM facturascli 
                WHERE fecha >= '{$fechaLimite}' 
                AND pagada = 0 
                LIMIT 20";
        
        $db = new \FacturaScripts\Core\Base\DataBase();
        $facturas = $db->select($sql);
        
        foreach ($facturas as $row) {
            if ($facturaModel->loadFromCode($row['idfactura'])) {
                $this->verificarFactura($facturaModel);
            }
        }
    }

    private function verificarFactura($factura): void
    {
        $recibos = $factura->getReceipts();
        if (count($recibos) !== 1) {
            return;
        }

        $formaPago = new \FacturaScripts\Dinamic\Model\FormaPago();
        if (!$formaPago->loadFromCode($factura->codpago)) {
            return;
        }

        if (strpos(strtolower($formaPago->descripcion), '30,60,90') === false) {
            return;
        }

        // Eliminar recibo único
        foreach ($recibos as $recibo) {
            $recibo->delete();
        }

        // Crear 3 recibos
        $recibosCreados = $this->crear3Recibos($factura);
        
        // Generar asiento de traspaso si se crearon los 3 recibos
        if ($recibosCreados === 3) {
            $this->generarAsientoTraspaso($factura);
        }
    }

    private function crear3Recibos($factura): int
    {
        $tercio = round($factura->total / 3, 2);
        $importes = [$tercio, $tercio, $factura->total - ($tercio * 2)];
        $recibosCreados = 0;
        
        foreach ([30, 60, 90] as $index => $dias) {
            $recibo = new \FacturaScripts\Dinamic\Model\ReciboCliente();
            $recibo->codcliente = $factura->codcliente;
            $recibo->fecha = $factura->fecha;
            $recibo->idempresa = $factura->idempresa;
            $recibo->idfactura = $factura->idfactura;
            $recibo->importe = $importes[$index];
            $recibo->codpago = $factura->codpago;
            $recibo->codigofactura = $factura->codigo;
            $recibo->coddivisa = $factura->coddivisa;
            $recibo->nick = $factura->nick;
            
            $fecha = new \DateTime($factura->fecha);
            $fecha->add(new \DateInterval("P{$dias}D"));
            $recibo->vencimiento = $fecha->format('Y-m-d');
            
            $recibo->numero = $this->siguienteNumero($factura->idempresa);
            $recibo->pagado = false;
            $recibo->observaciones = "Recibo " . ($index + 1) . "/3 - Vencimiento a {$dias} días de la Factura {$factura->codigo} de Fecha {$factura->fecha}";
            
            if ($recibo->save()) {
                $recibosCreados++;
            }
        }
        
        return $recibosCreados;
    }

    private function generarAsientoTraspaso($factura): void
    {
        $subcuentaCliente = $this->obtenerSubcuentaCliente($factura);
        if (!$subcuentaCliente) {
            return;
        }

        $subcuentaEfectos = $this->crearSubcuentaEfectos($subcuentaCliente);
        if (!$subcuentaEfectos) {
            return;
        }

        $asiento = new \FacturaScripts\Dinamic\Model\Asiento();
        $asiento->codejercicio = $factura->codejercicio;
        $asiento->concepto = "Traspaso recibos fraccionados - Factura " . $factura->codigo;
        $asiento->documento = $factura->codigo;
        $asiento->fecha = $factura->fecha;
        $asiento->idempresa = $factura->idempresa;
        $asiento->importe = $factura->total;
        $asiento->editable = true;

        if (!$asiento->save()) {
            return;
        }

        $this->crearLineaAsiento($asiento, $subcuentaEfectos, $factura->total, 0);
        $this->crearLineaAsiento($asiento, $subcuentaCliente, 0, $factura->total);
    }

    private function obtenerSubcuentaCliente($factura): ?object
    {
        if (empty($factura->cifnif)) {
            return null;
        }
        
        $ultimosDigitos = $this->extraerUltimos4Digitos($factura->cifnif);
        $codigoSubcuenta = '430000' . $ultimosDigitos;
        
        $subcuenta = new \FacturaScripts\Dinamic\Model\Subcuenta();
        $where = [
            new DataBaseWhere('codsubcuenta', $codigoSubcuenta),
            new DataBaseWhere('codejercicio', $factura->codejercicio)
        ];
        
        $subcuentas = $subcuenta->all($where, [], 0, 1);
        return empty($subcuentas) ? null : $subcuentas[0];
    }

    private function extraerUltimos4Digitos($cifnif): string
    {
        $soloNumeros = preg_replace('/[^0-9]/', '', $cifnif);
        return str_pad(substr($soloNumeros, -4), 4, '0', STR_PAD_LEFT);
    }

    private function crearSubcuentaEfectos($subcuentaCliente): ?object
    {
        $codigoEfectos = str_replace('4300', '4310', $subcuentaCliente->codsubcuenta);
        
        $subcuentaExistente = new \FacturaScripts\Dinamic\Model\Subcuenta();
        $where = [
            new DataBaseWhere('codsubcuenta', $codigoEfectos),
            new DataBaseWhere('codejercicio', $subcuentaCliente->codejercicio)
        ];
        
        $subcuentas = $subcuentaExistente->all($where, [], 0, 1);
        if (!empty($subcuentas)) {
            return $subcuentas[0];
        }
        
        // Buscar o crear cuenta padre 431
        $cuenta431 = new \FacturaScripts\Dinamic\Model\Cuenta();
        $whereCuenta = [
            new DataBaseWhere('codcuenta', '431'),
            new DataBaseWhere('codejercicio', $subcuentaCliente->codejercicio)
        ];
        $cuentas431 = $cuenta431->all($whereCuenta, [], 0, 1);
        
        if (empty($cuentas431)) {
            // Crear cuenta 431
            $cuenta431 = new \FacturaScripts\Dinamic\Model\Cuenta();
            $cuenta431->codcuenta = '431';
            $cuenta431->descripcion = 'Efectos a cobrar';
            $cuenta431->codejercicio = $subcuentaCliente->codejercicio;
            
            if (!$cuenta431->save()) {
                return null;
            }
        } else {
            $cuenta431 = $cuentas431[0];
        }
        
        $nuevaSubcuenta = new \FacturaScripts\Dinamic\Model\Subcuenta();
        $nuevaSubcuenta->codsubcuenta = $codigoEfectos;
        $nuevaSubcuenta->descripcion = str_replace('430', '431 - Efectos a cobrar', $subcuentaCliente->descripcion);
        $nuevaSubcuenta->codcuenta = '431';
        $nuevaSubcuenta->codejercicio = $subcuentaCliente->codejercicio;
        $nuevaSubcuenta->idcuenta = $cuenta431->idcuenta;
        
        return $nuevaSubcuenta->save() ? $nuevaSubcuenta : null;
    }

    private function crearLineaAsiento($asiento, $subcuenta, $debe, $haber): void
    {
        $partida = new \FacturaScripts\Dinamic\Model\Partida();
        $partida->idasiento = $asiento->idasiento;
        $partida->codsubcuenta = $subcuenta->codsubcuenta;
        $partida->idsubcuenta = $subcuenta->idsubcuenta;
        $partida->concepto = $asiento->concepto;
        $partida->debe = $debe;
        $partida->haber = $haber;
        $partida->save();
    }

    private function siguienteNumero($idempresa): int
    {
        $db = new \FacturaScripts\Core\Base\DataBase();
        $sql = "SELECT COALESCE(MAX(numero), 0) + 1 as num FROM recibospagoscli WHERE idempresa = " . (int)$idempresa;
        $data = $db->select($sql);
        return empty($data) ? 1 : (int)$data[0]['num'];
    }
}