'use client';

import { useEffect, useState } from 'react';
import { useAuth } from '@/lib/auth-context';
import { adminApiFetch } from '@/lib/api';
import { useToast } from '@/lib/toast';
import { TableSkeleton } from '@/components/Skeletons';

type MatrixRow = {
  role: { id: number; name: string };
  permissions: { permission: { id: number; key: string }; granted: boolean }[];
};

// Meta Business Suite -> Business Settings -> People style checkbox grid:
// rows are roles, columns are permissions, cells are togglable — this IS
// the RBAC system, not a display of it. Toggling a cell calls
// PATCH /admin/roles/permission, which only SUPER_ADMIN can reach
// (requirePermission('can_manage_roles') on the API side).
export default function RolesPage() {
  const { accessToken, appSecretProof } = useAuth();
  const { show } = useToast();
  const [matrix, setMatrix] = useState<MatrixRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!accessToken || !appSecretProof) return;
    setLoading(true);
    adminApiFetch('/admin/roles', accessToken, appSecretProof)
      .then((d) => setMatrix(d.matrix || []))
      .catch(() => setError('You do not have permission to view this page.'))
      .finally(() => setLoading(false));
  }, [accessToken, appSecretProof]); // eslint-disable-line react-hooks/exhaustive-deps

  async function toggle(roleId: number, roleName: string, permissionId: number, permissionKey: string, grant: boolean) {
    if (!accessToken || !appSecretProof) return;
    // Optimistic update — flip the checkbox immediately, roll back on failure.
    setMatrix((m) => m.map((row) => row.role.id === roleId
      ? { ...row, permissions: row.permissions.map((p) => p.permission.id === permissionId ? { ...p, granted: grant } : p) }
      : row));
    try {
      await adminApiFetch('/admin/roles/permission', accessToken, appSecretProof, {
        method: 'PATCH',
        body: JSON.stringify({ roleId, permissionId, grant }),
      });
      show('success', `${grant ? 'Granted' : 'Revoked'} ${permissionKey} for ${roleName}.`);
    } catch {
      setMatrix((m) => m.map((row) => row.role.id === roleId
        ? { ...row, permissions: row.permissions.map((p) => p.permission.id === permissionId ? { ...p, granted: !grant } : p) }
        : row));
      show('error', 'Could not update that permission.');
    }
  }

  if (error) return <p className="text-sm text-brand-red">{error}</p>;
  if (loading) return <TableSkeleton rows={5} cols={6} />;
  if (matrix.length === 0) return null;

  const permissions = matrix[0].permissions.map((p) => p.permission);

  return (
    <div>
      <h1 className="text-lg font-bold mb-1">Roles & Permissions</h1>
      <p className="text-xs text-gray-500 mb-4">SUPER_ADMIN always has every permission and can&apos;t be edited here — that row is a floor, not a toggle.</p>
      <div className="bg-white border border-brand-border rounded-xl overflow-x-auto">
        <table className="text-sm min-w-[900px]">
          <thead className="bg-brand-bg text-left text-xs text-gray-500">
            <tr>
              <th className="px-4 py-2 sticky left-0 bg-brand-bg">Role</th>
              {permissions.map((p) => <th key={p.id} className="px-3 py-2 whitespace-nowrap">{p.key}</th>)}
            </tr>
          </thead>
          <tbody>
            {matrix.map((row) => (
              <tr key={row.role.id} className="border-t border-brand-border transition-colors hover:bg-brand-bg">
                <td className="px-4 py-2 font-medium sticky left-0 bg-white">{row.role.name}</td>
                {row.permissions.map((cell) => (
                  <td key={cell.permission.id} className="px-3 py-2 text-center">
                    <input
                      type="checkbox"
                      checked={cell.granted}
                      disabled={row.role.name === 'SUPER_ADMIN'}
                      onChange={(e) => toggle(row.role.id, row.role.name, cell.permission.id, cell.permission.key, e.target.checked)}
                      className="accent-brand-red transition-transform hover:scale-110"
                    />
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
