<?php

namespace Daniv04\HaciendaPackage\Services\Validators;

use Daniv04\HaciendaPackage\Exceptions\InvalidReceiptException;
use Daniv04\HaciendaPackage\Services\InvoicingService;

class PayloadStructureValidator
{
    private const REQUIRED_TOP_LEVEL_SECTIONS = [
        'Encabezado',
        'Clave',
        'Emisor',
        'DetalleServicio',
        'ResumenFactura',
    ];

    private const RECEPTOR_REQUIRED_TYPES = ['FE', 'FEE', 'FEC'];

    public function validate(array $payload, string $receiptType): void
    {
        $errors = [];

        // Check all required top-level sections exist
        foreach (self::REQUIRED_TOP_LEVEL_SECTIONS as $section) {
            if (!isset($payload[$section]) || empty($payload[$section])) {
                $errors[] = "Sección requerida: {$section}";
            }
        }

        // Validate Encabezado
        if (!isset($payload['Encabezado']['FechaEmision'])) {
            $errors[] = "Encabezado.FechaEmision es requerido";
        }

        // Validate Clave structure
        if (isset($payload['Clave'])) {
            if (empty($payload['Clave']['Sucursal']) || empty($payload['Clave']['Terminal']) ||
                empty($payload['Clave']['TipoComprobante'])) {
                $errors[] = "Clave requiere: Sucursal, Terminal, TipoComprobante";
            }
        }

        // Validate Emisor
        if (isset($payload['Emisor'])) {
            if (empty($payload['Emisor']['Nombre'])) {
                $errors[] = "Emisor.Nombre es requerido";
            }
            if (empty($payload['Emisor']['Identificacion']['Numero'])) {
                $errors[] = "Emisor.Identificacion.Numero es requerido";
            }
            if (empty($payload['Emisor']['Identificacion']['Tipo'])) {
                $errors[] = "Emisor.Identificacion.Tipo es requerido";
            }
        }

        // Validate Receptor if required for this type
        if (in_array($receiptType, self::RECEPTOR_REQUIRED_TYPES)) {
            if (empty($payload['Receptor']['Nombre']) || empty($payload['Receptor']['Identificacion']['Numero'])) {
                $errors[] = "Para tipo {$receiptType}, Receptor.Nombre y Receptor.Identificacion.Numero son requeridos";
            }
        }

        // Validate DetalleServicio has at least one line
        if (isset($payload['DetalleServicio'])) {
            if (empty($payload['DetalleServicio']['LineaDetalle']) || !is_array($payload['DetalleServicio']['LineaDetalle'])) {
                $errors[] = "DetalleServicio.LineaDetalle debe ser un array no vacío";
            } else {
                // Validate each line has required fields
                foreach ($payload['DetalleServicio']['LineaDetalle'] as $index => $line) {
                    if (empty($line['Cantidad']) || empty($line['PrecioUnitario']) || empty($line['MontoTotalLinea'])) {
                        $errors[] = "LineaDetalle[{$index}]: requiere Cantidad, PrecioUnitario, MontoTotalLinea";
                    }
                }
            }
        }

        // Validate ResumenFactura
        if (isset($payload['ResumenFactura'])) {
            if (!isset($payload['ResumenFactura']['TotalComprobante'])) {
                $errors[] = "ResumenFactura.TotalComprobante es requerido";
            }
            if (!isset($payload['ResumenFactura']['CodigoTipoMoneda'])) {
                $errors[] = "ResumenFactura.CodigoTipoMoneda es requerido";
            }
        }

        if (!empty($errors)) {
            throw new InvalidReceiptException(
                "Estructura de payload inválida:\n" . implode("\n", $errors)
            );
        }
    }
}
