import type { FC } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { Save, Info, Lock } from 'lucide-react';
import { Button, Skeleton, toast } from './ui';
import { odooApi, type FrontendRole } from '../services/odoo';
import { ROLE_LABELS } from '../lib/auth';
import { MENU_ITEMS } from '../lib/menu-items';

const ROLES = Object.keys(ROLE_LABELS) as FrontendRole[];

type Matrix = Record<string, FrontendRole[]>;

const RolesPanel: FC = () => {
  const [matrix, setMatrix] = useState<Matrix | null>(null);
  const [saved, setSaved] = useState<Matrix | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    try {
      setLoading(true);
      const res = await odooApi.getRolePermissions();
      if (res.status === 'success') {
        setMatrix(res.matrix);
        setSaved(res.matrix);
      } else {
        toast.error(res.message || 'No se pudieron cargar los permisos');
      }
    } catch (err) {
      toast.error('Error al cargar permisos por rol');
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  const dirty = matrix !== null && saved !== null && JSON.stringify(matrix) !== JSON.stringify(saved);

  const toggle = (href: string, role: FrontendRole) => {
    if (!matrix) return;
    if (href === '/configuracion' && role === 'admin') return; // siempre requerido
    const current = matrix[href] || [];
    const next = current.includes(role) ? current.filter((r) => r !== role) : [...current, role];
    setMatrix({ ...matrix, [href]: next });
  };

  const save = async () => {
    if (!matrix) return;
    try {
      setSaving(true);
      const res = await odooApi.updateRolePermissions(matrix);
      if (res.status === 'success') {
        setMatrix(res.matrix);
        setSaved(res.matrix);
        toast.success('Permisos por rol guardados');
      } else {
        toast.error(res.message || 'No se pudieron guardar los permisos');
      }
    } catch (err) {
      const msg = (err as { response?: { data?: { message?: string } } })?.response?.data?.message;
      toast.error(msg || 'Error al guardar permisos');
      console.error(err);
    } finally {
      setSaving(false);
    }
  };

  if (loading || !matrix) {
    return <Skeleton count={6} className="h-10 w-full" />;
  }

  return (
    <div>
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4">
        <p className="text-sm text-theme-muted flex items-start gap-2 max-w-2xl">
          <Info size={16} className="mt-0.5 shrink-0" />
          Aplica a todos los usuarios del rol al recargar su sesión. Los permisos personales de un usuario van encima.
        </p>
        <div className="flex items-center gap-3 shrink-0">
          {dirty && <span className="text-xs font-medium text-amber-600">Cambios sin guardar</span>}
          <Button onClick={save} loading={saving} disabled={!dirty}>
            <Save size={16} className="mr-2" />
            Guardar
          </Button>
        </div>
      </div>

      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead className="bg-theme-bg text-theme-muted text-xs uppercase">
            <tr>
              <th className="text-left px-3 py-2 sticky left-0 bg-theme-bg">Sección</th>
              {ROLES.map((r) => (
                <th key={r} className="px-2 py-2 text-center font-medium">{ROLE_LABELS[r]}</th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-theme-border">
            {MENU_ITEMS.map((item) => (
              <tr key={item.href} className="hover:bg-theme-bg">
                <td className="px-3 py-2 font-medium text-theme-heading whitespace-nowrap sticky left-0 bg-theme-surface">
                  {item.label}
                </td>
                {ROLES.map((role) => {
                  const locked = item.href === '/configuracion' && role === 'admin';
                  const checked = (matrix[item.href] || []).includes(role);
                  return (
                    <td key={role} className="px-2 py-2 text-center">
                      <input
                        type="checkbox"
                        checked={checked}
                        disabled={locked}
                        onChange={() => toggle(item.href, role)}
                        title={locked ? 'El admin siempre requiere Configuración' : `${item.label} — ${ROLE_LABELS[role]}`}
                        className="rounded border-theme-border-strong disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer"
                      />
                      {locked && <Lock size={10} className="inline ml-1 text-theme-muted" />}
                    </td>
                  );
                })}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export default RolesPanel;
