<?php

namespace App\Services;

use App\Models\WorkflowEstado;
use App\Models\WorkflowTransicion;
use App\Models\WorkflowEtapa;
use App\Models\WorkflowSla;
use Illuminate\Support\Facades\Cache;

class WorkflowConfigService
{
    // ═══════ DEFAULTS (fallback si BD vacía) ═══════
    const DEFAULT_ESTADOS = [
        'recepcion' => ['nombre' => 'Recepción', 'color' => 'gray', 'icono' => '📥', 'orden' => 1, 'es_inicial' => true],
        'analisis' => ['nombre' => 'Análisis', 'color' => 'blue', 'icono' => '🔍', 'orden' => 2],
        'redaccion' => ['nombre' => 'Redacción', 'color' => 'yellow', 'icono' => '✍️', 'orden' => 3],
        'revision' => ['nombre' => 'Revisión', 'color' => 'purple', 'icono' => '👁️', 'orden' => 4],
        'radicado' => ['nombre' => 'Radicado', 'color' => 'indigo', 'icono' => '📋', 'orden' => 5],
        'seguimiento' => ['nombre' => 'Seguimiento', 'color' => 'cyan', 'icono' => '📡', 'orden' => 6],
        'sentencia' => ['nombre' => 'Sentencia', 'color' => 'orange', 'icono' => '⚖️', 'orden' => 7],
        'liquidacion' => ['nombre' => 'Liquidación', 'color' => 'emerald', 'icono' => '💰', 'orden' => 8],
        'terminado' => ['nombre' => 'Terminado', 'color' => 'green', 'icono' => '✅', 'orden' => 9, 'es_final' => true],
    ];

    const DEFAULT_TRANSICIONES = [
        'recepcion' => ['analisis'],
        'analisis' => ['redaccion', 'terminado'],
        'redaccion' => ['revision'],
        'revision' => ['redaccion', 'radicado'],
        'radicado' => ['seguimiento'],
        'seguimiento' => ['sentencia', 'terminado'],
        'sentencia' => ['liquidacion', 'terminado'],
        'liquidacion' => ['terminado'],
        'terminado' => [],
    ];

    const DEFAULT_ETAPAS = [
        'na' => 'N/A', 'calificacion' => 'Calificación', 'mandamiento' => 'Mandamiento de Pago',
        'notificacion' => 'Notificación', 'excepciones' => 'Excepciones',
        'medidas_cautelares' => 'Medidas Cautelares', 'sentencia' => 'Sentencia',
        'liquidacion' => 'Liquidación', 'remate' => 'Remate', 'audiencia' => 'Audiencia',
    ];

    /**
     * Obtener estados como array [slug => nombre]
     */
    public static function estados(): array
    {
        return Cache::remember('wf_estados', 3600, function () {
            $estados = WorkflowEstado::activos()->pluck('nombre', 'slug')->toArray();
            return !empty($estados) ? $estados : array_map(fn($e) => $e['nombre'], self::DEFAULT_ESTADOS);
        });
    }

    /**
     * Obtener estados con metadata completa [slug => {nombre, color, icono, orden, ...}]
     */
    public static function estadosCompletos(): array
    {
        return Cache::remember('wf_estados_full', 3600, function () {
            $estados = WorkflowEstado::activos()->get();
            if ($estados->isEmpty()) {
                return self::DEFAULT_ESTADOS;
            }
            $result = [];
            foreach ($estados as $e) {
                $result[$e->slug] = [
                    'id' => $e->id,
                    'nombre' => $e->nombre,
                    'color' => $e->color,
                    'icono' => $e->icono,
                    'orden' => $e->orden,
                    'es_inicial' => $e->es_inicial,
                    'es_final' => $e->es_final,
                ];
            }
            return $result;
        });
    }

    /**
     * Obtener color de un estado por slug
     */
    public static function colorEstado(string $slug): string
    {
        $estados = self::estadosCompletos();
        return $estados[$slug]['color'] ?? 'gray';
    }

    /**
     * Obtener icono de un estado por slug
     */
    public static function iconoEstado(string $slug): string
    {
        $estados = self::estadosCompletos();
        return $estados[$slug]['icono'] ?? '⚪';
    }

    /**
     * Obtener transiciones permitidas para un estado [slug => [slug_destino1, slug_destino2, ...]]
     */
    public static function transiciones(): array
    {
        return Cache::remember('wf_transiciones', 3600, function () {
            $trans = WorkflowTransicion::activas()
                ->with(['origen', 'destino'])
                ->get();

            if ($trans->isEmpty()) {
                return self::DEFAULT_TRANSICIONES;
            }

            $result = [];
            foreach ($trans as $t) {
                $origen = $t->origen->slug;
                $destino = $t->destino->slug;
                $result[$origen][] = $destino;
            }

            // Asegurar que todos los estados tengan entrada
            foreach (self::estados() as $slug => $nombre) {
                if (!isset($result[$slug])) {
                    $result[$slug] = [];
                }
            }

            return $result;
        });
    }

    /**
     * Obtener transiciones permitidas para un estado específico
     */
    public static function transicionesDesde(string $estadoSlug): array
    {
        $trans = self::transiciones();
        return $trans[$estadoSlug] ?? [];
    }

    /**
     * Verificar si una transición es válida
     */
    public static function puedeTransicionar(string $origen, string $destino): bool
    {
        $permitidas = self::transicionesDesde($origen);
        return in_array($destino, $permitidas);
    }

    /**
     * Obtener etapas procesales [slug => nombre]
     */
    public static function etapas(): array
    {
        return Cache::remember('wf_etapas', 3600, function () {
            $etapas = WorkflowEtapa::activas()->pluck('nombre', 'slug')->toArray();
            return !empty($etapas) ? $etapas : self::DEFAULT_ETAPAS;
        });
    }

    /**
     * Obtener SLA para un estado y cliente (o global)
     */
    public static function sla(string $estadoSlug, ?int $clienteId = null): array
    {
        $cacheKey = "wf_sla_{$estadoSlug}_{$clienteId}";
        return Cache::remember($cacheKey, 3600, function () use ($estadoSlug, $clienteId) {
            $estado = WorkflowEstado::where('slug', $estadoSlug)->first();
            if (!$estado) {
                return ['dias_verde' => 3, 'dias_amarillo' => 5, 'dias_rojo' => 7];
            }

            // Buscar SLA específico del cliente primero, luego global
            $sla = WorkflowSla::where('estado_id', $estado->id)
                ->where('activo', true)
                ->where(function ($q) use ($clienteId) {
                    $q->where('cliente_corporativo_id', $clienteId)
                      ->orWhereNull('cliente_corporativo_id');
                })
                ->orderByRaw('cliente_corporativo_id IS NULL ASC') // Específico primero
                ->first();

            if ($sla) {
                return [
                    'dias_verde' => $sla->dias_verde,
                    'dias_amarillo' => $sla->dias_amarillo,
                    'dias_rojo' => $sla->dias_rojo,
                ];
            }

            return ['dias_verde' => 3, 'dias_amarillo' => 5, 'dias_rojo' => 7];
        });
    }

    /**
     * Calcular semáforo para un proceso
     */
    public static function calcularSemaforo(string $estadoSlug, int $diasEnEstado, ?int $clienteId = null): string
    {
        $estados = self::estadosCompletos();
        $meta = $estados[$estadoSlug] ?? null;

        // Estados finales siempre verde
        if ($meta && ($meta['es_final'] ?? false)) {
            return 'verde';
        }

        $sla = self::sla($estadoSlug, $clienteId);

        if ($diasEnEstado >= $sla['dias_rojo']) return 'rojo';
        if ($diasEnEstado >= $sla['dias_amarillo']) return 'amarillo';
        return 'verde';
    }

    /**
     * Limpiar todo el cache de workflow
     */
    public static function limpiarCache(): void
    {
        Cache::forget('wf_estados');
        Cache::forget('wf_estados_full');
        Cache::forget('wf_transiciones');
        Cache::forget('wf_etapas');

        // Limpiar SLAs (pattern)
        $estados = WorkflowEstado::pluck('slug');
        foreach ($estados as $slug) {
            Cache::forget("wf_sla_{$slug}_");
            // Limpiar para todos los clientes conocidos
            $clientes = \App\Models\ClienteCorporativo::pluck('id');
            foreach ($clientes as $cid) {
                Cache::forget("wf_sla_{$slug}_{$cid}");
            }
        }
    }

    /**
     * Obtener estado inicial
     */
    public static function estadoInicial(): string
    {
        $estados = self::estadosCompletos();
        foreach ($estados as $slug => $meta) {
            if ($meta['es_inicial'] ?? false) return $slug;
        }
        return array_key_first($estados) ?? 'recepcion';
    }

    /**
     * Obtener prioridades (estas se mantienen fijas por ahora)
     */
    public static function prioridades(): array
    {
        return [
            'baja' => '🟢 Baja',
            'media' => '🟡 Media',
            'alta' => '🟠 Alta',
            'urgente' => '🔴 Urgente',
        ];
    }
}
