<?php

declare(strict_types=1);

namespace App\Services;

use App\Core\Database;

class PurchaseOrderNotificationService
{
    private NotificationChannelService $notifier;
    /** @var array<string,bool> */
    private array $columnAvailabilityCache = [];

    public function __construct(?NotificationChannelService $notifier = null)
    {
        $this->notifier = $notifier ?? new NotificationChannelService();
    }

    public function sendToSupplier(int $companyId, int $orderId): array
    {
        if ($companyId <= 0 || $orderId <= 0) {
            return [
                'ok' => false,
                'error' => 'Datos inválidos para enviar OC.',
                'response' => null,
            ];
        }

        if (!$this->notifier->isChannelEnabled('email')) {
            return [
                'ok' => false,
                'error' => 'Canal email desactivado.',
                'response' => null,
            ];
        }

        $pdo = Database::connection();
        $headerStmt = $pdo->prepare(
            'SELECT
                oc.id,
                oc.numero,
                oc.fecha,
                oc.subtotal,
                oc.impuestos,
                oc.total,
                oc.observacion,
                p.nombre AS proveedor_nombre,
                p.email AS proveedor_email,
                e.nombre AS empresa_nombre,
                e.nit AS empresa_nit,
                e.telefono AS empresa_telefono,
                e.email AS empresa_email,
                s.nombre AS sucursal_nombre
             FROM ordenes_compra oc
             INNER JOIN proveedores p ON p.id = oc.proveedor_id
             INNER JOIN empresas e ON e.id = oc.empresa_id
             LEFT JOIN sucursales s ON s.id = oc.sucursal_id
             WHERE oc.empresa_id = :empresa_id
               AND oc.id = :id
             LIMIT 1'
        );
        $headerStmt->execute([
            ':empresa_id' => $companyId,
            ':id' => $orderId,
        ]);
        $header = $headerStmt->fetch();

        if (!is_array($header)) {
            return [
                'ok' => false,
                'error' => 'No se encontró la orden de compra.',
                'response' => null,
            ];
        }

        $supplierEmail = strtolower(trim((string) ($header['proveedor_email'] ?? '')));
        if ($supplierEmail === '' || !filter_var($supplierEmail, FILTER_VALIDATE_EMAIL)) {
            return [
                'ok' => false,
                'error' => 'El proveedor no tiene un correo válido para envío automático.',
                'response' => null,
            ];
        }

        $hasVariantColumn = $this->tableHasColumn($pdo, 'orden_compra_detalles', 'variante_id');
        $variantSelect = $hasVariantColumn ? ', v.nombre AS variante_nombre' : ', NULL AS variante_nombre';
        $variantJoin = $hasVariantColumn ? ' LEFT JOIN producto_variantes v ON v.id = od.variante_id AND v.empresa_id = od.empresa_id ' : '';

        $detailStmt = $pdo->prepare(
            'SELECT
                od.cantidad,
                od.costo_unitario,
                od.impuesto,
                od.total_linea,
                p.nombre AS producto,
                p.sku
                ' . $variantSelect . '
             FROM orden_compra_detalles od
             INNER JOIN productos p ON p.id = od.producto_id
             ' . $variantJoin . '
             WHERE od.empresa_id = :empresa_id
               AND od.orden_compra_id = :orden_id
             ORDER BY od.id ASC'
        );
        $detailStmt->execute([
            ':empresa_id' => $companyId,
            ':orden_id' => $orderId,
        ]);
        $details = $detailStmt->fetchAll() ?: [];

        $orderNumber = (string) ($header['numero'] ?? ('OC-' . $orderId));
        $subject = 'Orden de compra ' . $orderNumber;
        $pdfUrl = url('compras/ordenes/' . $orderId . '/pdf');

        $text = $this->buildText($header, $details, $pdfUrl);
        $html = $this->buildHtml($header, $details, $pdfUrl);

        return $this->notifier->sendEmail($supplierEmail, $subject, $text, $html);
    }

    private function buildText(array $header, array $details, string $pdfUrl): string
    {
        $company = trim((string) ($header['empresa_nombre'] ?? ''));
        $supplier = trim((string) ($header['proveedor_nombre'] ?? ''));
        $number = trim((string) ($header['numero'] ?? ''));
        $date = trim((string) ($header['fecha'] ?? ''));

        $lines = [];
        foreach ($details as $item) {
            $name = trim((string) ($item['producto'] ?? 'Producto'));
            $variantName = trim((string) ($item['variante_nombre'] ?? ''));
            if ($variantName !== '') {
                $name .= ' · ' . $variantName;
            }
            $qty = (int) round((float) ($item['cantidad'] ?? 0));
            $cost = money((float) ($item['costo_unitario'] ?? 0));
            $lines[] = '- ' . $name . ' | Cant: ' . $qty . ' | Costo: ' . $cost;
        }

        return trim(
            'Hola ' . ($supplier !== '' ? $supplier : 'proveedor') . ',' . "\n\n"
            . 'Adjuntamos la orden de compra emitida por ' . ($company !== '' ? $company : 'la empresa') . '.' . "\n"
            . 'OC: ' . $number . "\n"
            . 'Fecha: ' . $date . "\n"
            . 'Total: ' . money((float) ($header['total'] ?? 0)) . "\n\n"
            . "Detalle:\n"
            . implode("\n", $lines) . "\n\n"
            . 'Descargar PDF: ' . $pdfUrl
        );
    }

    private function buildHtml(array $header, array $details, string $pdfUrl): string
    {
        $supplier = htmlspecialchars((string) ($header['proveedor_nombre'] ?? 'Proveedor'), ENT_QUOTES, 'UTF-8');
        $company = htmlspecialchars((string) ($header['empresa_nombre'] ?? 'Veltrix POS'), ENT_QUOTES, 'UTF-8');
        $number = htmlspecialchars((string) ($header['numero'] ?? ''), ENT_QUOTES, 'UTF-8');
        $date = htmlspecialchars((string) ($header['fecha'] ?? ''), ENT_QUOTES, 'UTF-8');
        $branch = htmlspecialchars((string) ($header['sucursal_nombre'] ?? 'Sin sucursal'), ENT_QUOTES, 'UTF-8');
        $total = htmlspecialchars(money((float) ($header['total'] ?? 0)), ENT_QUOTES, 'UTF-8');
        $safePdfUrl = htmlspecialchars($pdfUrl, ENT_QUOTES, 'UTF-8');
        $safeYear = htmlspecialchars(date('Y'), ENT_QUOTES, 'UTF-8');

        $rows = '';
        foreach ($details as $item) {
            $name = trim((string) ($item['producto'] ?? 'Producto'));
            $sku = trim((string) ($item['sku'] ?? ''));
            $variantName = trim((string) ($item['variante_nombre'] ?? ''));
            if ($sku !== '') {
                $name .= ' [' . $sku . ']';
            }
            if ($variantName !== '') {
                $name .= ' · ' . $variantName;
            }

            $rows .= '<tr>'
                . '<td style="padding:8px;border-bottom:1px solid #edf2fb;">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</td>'
                . '<td style="padding:8px;border-bottom:1px solid #edf2fb;text-align:right;">' . (int) round((float) ($item['cantidad'] ?? 0)) . '</td>'
                . '<td style="padding:8px;border-bottom:1px solid #edf2fb;text-align:right;">' . htmlspecialchars(money((float) ($item['costo_unitario'] ?? 0)), ENT_QUOTES, 'UTF-8') . '</td>'
                . '<td style="padding:8px;border-bottom:1px solid #edf2fb;text-align:right;">' . htmlspecialchars(money((float) ($item['total_linea'] ?? 0)), ENT_QUOTES, 'UTF-8') . '</td>'
                . '</tr>';
        }

        if ($rows === '') {
            $rows = '<tr><td colspan="4" style="padding:10px;text-align:center;color:#64748b;">Sin líneas de detalle</td></tr>';
        }

        return '<!doctype html><html lang="es"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Orden de compra</title></head>'
            . '<body style="margin:0;padding:0;background:#f2f6fc;font-family:Arial,Helvetica,sans-serif;color:#1f2a3d;">'
            . '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="padding:20px 10px;background:#f2f6fc;"><tr><td align="center">'
            . '<table role="presentation" width="680" cellspacing="0" cellpadding="0" style="max-width:680px;width:100%;background:#fff;border:1px solid #dce5f4;border-radius:14px;overflow:hidden;">'
            . '<tr><td style="padding:20px 24px;background:linear-gradient(135deg,#14213d 0%,#1a6b9b 100%);color:#fff;">'
            . '<div style="font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:#fff;">Orden de compra</div>'
            . '<h1 style="margin:8px 0 0;font-size:26px;line-height:1.2;color:#fff;">' . $number . '</h1>'
            . '<p style="margin:8px 0 0;color:#fff;opacity:.95;">Hola ' . $supplier . ', te compartimos una OC emitida por ' . $company . '.</p>'
            . '</td></tr>'
            . '<tr><td style="padding:18px 24px;">'
            . '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="margin-bottom:12px;">'
            . '<tr><td style="padding:2px 0;color:#6b7a96;">Fecha</td><td style="padding:2px 0;text-align:right;font-weight:700;">' . $date . '</td></tr>'
            . '<tr><td style="padding:2px 0;color:#6b7a96;">Sucursal</td><td style="padding:2px 0;text-align:right;font-weight:700;">' . $branch . '</td></tr>'
            . '<tr><td style="padding:2px 0;color:#6b7a96;">Total OC</td><td style="padding:2px 0;text-align:right;font-weight:700;color:#0d6ba3;">' . $total . '</td></tr>'
            . '</table>'
            . '<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="border:1px solid #e4ebf7;border-radius:10px;overflow:hidden;">'
            . '<thead><tr style="background:#f7fbff;"><th style="padding:9px;text-align:left;font-size:12px;color:#5f759f;">Producto</th><th style="padding:9px;text-align:right;font-size:12px;color:#5f759f;">Cantidad</th><th style="padding:9px;text-align:right;font-size:12px;color:#5f759f;">Costo</th><th style="padding:9px;text-align:right;font-size:12px;color:#5f759f;">Total</th></tr></thead>'
            . '<tbody>' . $rows . '</tbody></table>'
            . '<p style="margin:14px 0 0;">'
            . '<a href="' . $safePdfUrl . '" style="display:inline-block;padding:11px 18px;border-radius:999px;background:#0b8fad;color:#fff;text-decoration:none;font-weight:700;">Descargar PDF OC</a>'
            . '</p>'
            . '</td></tr>'
            . '<tr><td style="padding:12px 24px;background:#f7faff;border-top:1px solid #e2e9f6;font-size:12px;color:#7c8faa;">Veltrix POS · ' . $safeYear . '</td></tr>'
            . '</table></td></tr></table></body></html>';
    }

    private function tableHasColumn(\PDO $pdo, string $table, string $column): bool
    {
        $cacheKey = $table . '.' . $column;
        if (array_key_exists($cacheKey, $this->columnAvailabilityCache)) {
            return $this->columnAvailabilityCache[$cacheKey];
        }

        $stmt = $pdo->prepare(
            "SELECT COUNT(*) FROM information_schema.COLUMNS
             WHERE TABLE_SCHEMA = DATABASE()
               AND TABLE_NAME = :table
               AND COLUMN_NAME = :column"
        );
        $stmt->execute([
            ':table' => $table,
            ':column' => $column,
        ]);

        $this->columnAvailabilityCache[$cacheKey] = (int) $stmt->fetchColumn() > 0;
        return $this->columnAvailabilityCache[$cacheKey];
    }
}
