"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import dynamic from "next/dynamic";
import { Save, Settings, Users, Loader2 } from "lucide-react";
import Button from "@/components/ui/Button";
import { cn } from "@/lib/cn";
import { DEFAULT_USER_PERMISSIONS, PERMISSION_MODULES, permissionMapFromRecords, type PermissionFlags, type PermissionModule, type UserPermission } from "@/lib/permissions/domain";
import { ensureUserPermissionRows, listUserPermissions, listUsers, upsertUserPermission } from "@/lib/pb/user-permissions";
import { useAuthStore, isAdmin } from "@/lib/store/useAuthStore";
import type { User } from "@/lib/types";
import { listCrmConfigSla, updateCrmConfigSla } from "@/lib/pb/crm";
import { ESTADO_CRM_LABELS, type CrmConfigSla } from "@/lib/types/crm";
import { initPreciosSync } from "@/lib/calculadora/store";

const PreciosTab = dynamic(() => import("@/components/calculadora/PreciosTab"), { ssr: false });
const LogicaTab  = dynamic(() => import("@/components/calculadora/LogicaTab"),  { ssr: false });

const MODULE_LABELS: Record<PermissionModule, string> = {
  inicio: "Inicio",
  calculadora: "Calculadora",
  crm: "CRM",
  presupuestos: "Presupuestos",
  pedidos: "Pedidos",
  pipeline: "Pipeline",
  cortes: "Cortes",
  calendario: "Calendario",
  caja: "Caja / Contabilidad",
  chatwoot: "Mensajería",
  clientes: "Clientes",
  reportes: "Reportes",
  configuracion: "Configuración",
  proveedores: "Proveedores",
  catalogo: "Catálogo",
  tareas: "Tareas",
  agente: "Asistente IA (Richard)",
  disenador: "Diseñador",
};

const ACTIONS: Array<keyof PermissionFlags> = ["can_view", "can_create", "can_edit", "can_delete"];
const ACTION_LABELS: Record<keyof PermissionFlags, string> = {
  can_view: "Ver",
  can_create: "Crear",
  can_edit: "Editar",
  can_delete: "Borrar",
};

type MainTab = "usuarios" | "calculadora" | "crm";
type CalcSubTab = "precios" | "logica";

export default function ConfiguracionPage() {
  const currentUser = useAuthStore((s) => s.user);
  const refreshPermissions = useAuthStore((s) => s.refreshPermissions);

  // Tabs state
  const [activeTab, setActiveTab] = useState<MainTab>("usuarios");
  const [calcSubTab, setCalcSubTab] = useState<CalcSubTab>("precios");

  // User & permissions state
  const [users, setUsers] = useState<User[]>([]);
  const [selectedId, setSelectedId] = useState("");
  const [records, setRecords] = useState<UserPermission[]>([]);

  // CRM SLA state
  const [slaList, setSlaList] = useState<CrmConfigSla[]>([]);
  const [slaHours, setSlaHours] = useState<Record<string, string>>({});
  const [loadingSla, setLoadingSla] = useState(false);

  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState("");

  const calcSyncedRef = useRef(false);

  // Load users & initial defaults
  useEffect(() => {
    (async () => {
      try {
        const loaded = await listUsers();
        setUsers(loaded);
        setSelectedId(loaded[0]?.id || "");
      } catch (e) {
        setErr((e as Error).message || "No se pudieron cargar usuarios");
      }
    })();
  }, []);

  const selectedUser = users.find((user) => user.id === selectedId) || null;

  // Load user permissions
  useEffect(() => {
    if (!selectedUser) return;
    (async () => {
      setErr("");
      try {
        const loaded = await listUserPermissions(selectedUser.id);
        setRecords(loaded);
      } catch (e) {
        setErr((e as Error).message || "No se pudieron cargar permisos");
      }
    })();
  }, [selectedUser]);

  const permissionMap = useMemo(() => {
    if (!selectedUser) return null;
    return permissionMapFromRecords(selectedUser.role, records);
  }, [selectedUser, records]);

  // Load CRM SLAs
  const loadSlas = useCallback(async () => {
    setLoadingSla(true);
    setErr("");
    try {
      const list = await listCrmConfigSla();
      setSlaList(list);
      const hoursMap: Record<string, string> = {};
      list.forEach((s) => {
        hoursMap[s.id] = String(s.horas_limite);
      });
      setSlaHours(hoursMap);
    } catch (e) {
      setErr((e as Error).message || "No se pudieron cargar límites de tiempo");
    } finally {
      setLoadingSla(false);
    }
  }, []);

  useEffect(() => {
    if (activeTab === "crm") {
      loadSlas();
    }
  }, [activeTab, loadSlas]);

  // Init PB precios sync once, when the Calculadora tab is opened
  useEffect(() => {
    if (activeTab === "calculadora" && !calcSyncedRef.current) {
      calcSyncedRef.current = true;
      initPreciosSync();
    }
  }, [activeTab]);

  if (!currentUser || !isAdmin(currentUser)) return null;
  const canEdit = isAdmin(currentUser);

  async function seedDefaults() {
    if (!selectedUser) return;
    setSaving(true);
    setErr("");
    try {
      const rows = await ensureUserPermissionRows(selectedUser.id, DEFAULT_USER_PERMISSIONS[selectedUser.role]);
      setRecords(rows);
      if (currentUser && selectedUser.id === currentUser.id) await refreshPermissions();
    } catch (e) {
      setErr((e as Error).message || "No se pudieron restaurar permisos");
    } finally {
      setSaving(false);
    }
  }

  async function toggle(module: PermissionModule, action: keyof PermissionFlags) {
    if (!selectedUser || !permissionMap) return;
    const next = {
      ...permissionMap[module],
      [action]: !permissionMap[module][action],
    };
    setSaving(true);
    setErr("");
    try {
      const updated = await upsertUserPermission(selectedUser.id, module, next);
      setRecords((prev) => [...prev.filter((record) => record.module !== module), updated]);
      if (currentUser && selectedUser.id === currentUser.id) await refreshPermissions();
    } catch (e) {
      setErr((e as Error).message || "No se pudo guardar permiso");
    } finally {
      setSaving(false);
    }
  }

  async function handleUpdateSla(slaId: string) {
    const val = Number(slaHours[slaId]);
    if (isNaN(val) || val < 0) {
      setErr("El valor de horas debe ser un número entero positivo o cero");
      return;
    }
    setSaving(true);
    setErr("");
    try {
      const updated = await updateCrmConfigSla(slaId, val);
      setSlaList((prev) => prev.map((s) => (s.id === slaId ? updated : s)));
    } catch (e) {
      setErr((e as Error).message || "No se pudo actualizar el límite");
    } finally {
      setSaving(false);
    }
  }

  const MAIN_TABS: { id: MainTab; label: string }[] = [
    { id: "usuarios",    label: "Usuarios y Permisos" },
    { id: "calculadora", label: "Calculadora" },
    { id: "crm",         label: "CRM" },
  ];

  return (
    <div className="max-w-6xl space-y-5">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-2xl font-extrabold text-ink">
            <Settings className="h-6 w-6 text-brand-dark" /> Configuración
          </h1>
          <p className="text-sm text-ink-soft">Cada pestaña agrupa la configuración de un módulo.</p>
        </div>
        {activeTab === "usuarios" && (
          <Button type="button" variant="secondary" onClick={seedDefaults} loading={saving} disabled={!selectedUser}>
            <Save size={16} /> Restaurar permisos base
          </Button>
        )}
      </div>

      {err && <div className="rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-bad">{err}</div>}

      {/* Navigation Tabs (por módulo) */}
      <div className="flex border-b border-line gap-2">
        {MAIN_TABS.map((t) => (
          <button
            key={t.id}
            type="button"
            onClick={() => setActiveTab(t.id)}
            className={cn(
              "pb-2.5 px-4 text-sm font-bold border-b-2 transition-all outline-none",
              activeTab === t.id
                ? "border-brand text-brand-dark"
                : "border-transparent text-faint hover:text-ink"
            )}
          >
            {t.label}
          </button>
        ))}
      </div>

      {/* ── Usuarios y Permisos ──────────────────────────────────────────── */}
      {activeTab === "usuarios" && (
        <div className="space-y-4">
          <section className="card p-4">
            <label className="flex max-w-md flex-col gap-1.5">
              <span className="flex items-center gap-2 text-sm font-medium text-ink-soft"><Users size={15} /> Usuario</span>
              <select
                value={selectedId}
                onChange={(event) => setSelectedId(event.target.value)}
                className="h-11 rounded-xl border border-line bg-surface px-3 text-sm text-ink outline-none focus:border-brand"
              >
                {users.map((user) => (
                  <option key={user.id} value={user.id}>
                    {user.name || user.phone} · {user.role}
                  </option>
                ))}
              </select>
            </label>
          </section>

          {selectedUser && permissionMap && (
            <section className="overflow-hidden rounded-xl border border-line bg-surface">
              <div className="grid grid-cols-[minmax(150px,1fr)_repeat(4,88px)] border-b border-line bg-canvas px-3 py-2 text-xs font-extrabold uppercase text-faint">
                <span>Módulo</span>
                {ACTIONS.map((action) => <span key={action} className="text-center">{ACTION_LABELS[action]}</span>)}
              </div>
              <div className="divide-y divide-line">
                {PERMISSION_MODULES.map((module) => (
                  <div key={module} className="grid grid-cols-[minmax(150px,1fr)_repeat(4,88px)] items-center px-3 py-2">
                    <span className="text-sm font-semibold text-ink">{MODULE_LABELS[module]}</span>
                    {ACTIONS.map((action) => (
                      <label key={action} className="grid place-items-center">
                        <input
                          type="checkbox"
                          checked={permissionMap[module][action]}
                          disabled={saving}
                          onChange={() => toggle(module, action)}
                          className="h-4 w-4 accent-brand"
                        />
                      </label>
                    ))}
                  </div>
                ))}
              </div>
            </section>
          )}
        </div>
      )}

      {/* ── Calculadora (Lista de precios + Lógica) ──────────────────────── */}
      {activeTab === "calculadora" && (
        <div className="space-y-4 animate-in fade-in duration-200">
          {/* Sub-pestañas */}
          <div className="flex gap-2">
            {([
              { id: "precios", label: "Lista de precios" },
              { id: "logica",  label: "Lógica" },
            ] as { id: CalcSubTab; label: string }[]).map((s) => (
              <button
                key={s.id}
                type="button"
                onClick={() => setCalcSubTab(s.id)}
                className={cn(
                  "rounded-full px-4 py-1.5 text-sm font-semibold transition-colors outline-none",
                  calcSubTab === s.id
                    ? "bg-brand text-white"
                    : "bg-surface border border-line text-ink-soft hover:text-ink"
                )}
              >
                {s.label}
              </button>
            ))}
          </div>

          {calcSubTab === "precios" && <PreciosTab canEdit={canEdit} />}
          {calcSubTab === "logica"  && <LogicaTab  canEdit={canEdit} />}
        </div>
      )}

      {/* ── CRM (Tiempos Límite / SLAs) ──────────────────────────────────── */}
      {activeTab === "crm" && (
        <section className="space-y-4 animate-in fade-in duration-200">
          <div>
            <h2 className="text-sm font-bold text-ink">Tiempos límite (SLAs) por etapa</h2>
            <p className="text-xs text-ink-soft">Horas máximas que una oportunidad puede permanecer en cada etapa antes de marcarse como atrasada.</p>
          </div>
          <div className="rounded-xl border border-line bg-surface overflow-hidden">
            <div className="grid grid-cols-[minmax(180px,1fr)_150px_100px] border-b border-line bg-canvas px-4 py-2 text-xs font-extrabold uppercase text-faint">
              <span>Etapa del CRM</span>
              <span className="text-center">Horas Límite (SLA)</span>
              <span className="text-right">Acción</span>
            </div>

            {loadingSla ? (
              <div className="p-12 text-center text-xs text-faint flex items-center justify-center gap-2">
                <Loader2 className="animate-spin text-brand-dark" size={16} /> Cargando configuración...
              </div>
            ) : slaList.length === 0 ? (
              <div className="p-8 text-center text-xs text-faint">
                No se encontraron configuraciones de SLA.
              </div>
            ) : (
              <div className="divide-y divide-line">
                {slaList.map((sla) => {
                  const label = ESTADO_CRM_LABELS[sla.estado] || sla.estado;
                  const isClosedState = ["ganado", "perdido"].includes(sla.estado);
                  return (
                    <div key={sla.id} className="grid grid-cols-[minmax(180px,1fr)_150px_100px] items-center px-4 py-3">
                      <div>
                        <span className="text-sm font-semibold text-ink">{label}</span>
                        {isClosedState && (
                          <span className="ml-2 text-[10px] bg-canvas text-faint rounded px-1.5 py-0.5 font-bold uppercase">Finalizada</span>
                        )}
                      </div>
                      <div className="flex justify-center">
                        <input
                          type="number"
                          min="0"
                          disabled={saving || isClosedState}
                          value={slaHours[sla.id] || "0"}
                          onChange={(e) => setSlaHours({ ...slaHours, [sla.id]: e.target.value })}
                          className="w-24 h-9 rounded-lg border border-line bg-surface text-center text-sm font-bold text-ink focus:border-brand focus:ring-1 focus:ring-brand outline-none disabled:opacity-40"
                        />
                      </div>
                      <div className="flex justify-end">
                        <Button
                          type="button"
                          variant="secondary"
                          size="sm"
                          disabled={saving || isClosedState}
                          onClick={() => handleUpdateSla(sla.id)}
                        >
                          Guardar
                        </Button>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>

          <div className="bg-[#fffdf7] border border-line rounded-xl p-4 text-xs text-ink-soft space-y-1.5">
            <p className="font-bold text-ink flex items-center gap-1">💡 ¿Cómo funcionan los límites de tiempo (SLAs)?</p>
            <p>1. <b>Medición</b>: Cada oportunidad calcula el tiempo transcurrido en días y horas desde que ingresó a su etapa actual.</p>
            <p>2. <b>Alertas visuales</b>: Si una oportunidad supera el límite de horas establecido para su etapa, su tarjeta en el Kanban se marcará con borde de advertencia rojo y un indicador visual ⚠️.</p>
            <p>3. <b>Desactivación</b>: Configurar el límite en <code className="bg-canvas px-1 rounded">0</code> desactiva la alerta para esa etapa específica. Las etapas finales (Ganado/Perdido) no admiten alertas.</p>
          </div>
        </section>
      )}
    </div>
  );
}
