'use client';

import { useEffect, useState } from 'react';
import { Loader2, Pencil, Plus, ShieldCheck, Trash2 } from 'lucide-react';
import { AdminShell } from '@/components/id/admin-shell';
import { useAuth } from '@/components/id/auth-provider';
import { useToast } from '@/components/id/toast-provider';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { AdminPermission, AdminRole, apiFetch } from '@/lib/api';

type RoleFormState = {
  slug: string;
  name: string;
  description: string;
  permissionSlugs: string[];
};

const emptyForm: RoleFormState = { slug: '', name: '', description: '', permissionSlugs: [] };

export default function AdminRbacPage() {
  const { token, user } = useAuth();
  const { showToast } = useToast();
  const [roles, setRoles] = useState<AdminRole[]>([]);
  const [permissions, setPermissions] = useState<AdminPermission[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingRole, setEditingRole] = useState<AdminRole | null>(null);
  const [form, setForm] = useState<RoleFormState>(emptyForm);

  async function reloadRoles() {
    if (!token) return;
    const response = await apiFetch<{ roles: AdminRole[] }>('/admin/rbac/roles', {}, token);
    setRoles(response.roles ?? []);
  }

  useEffect(() => {
    if (!token || !user?.canManageRoles) return;
    Promise.all([
      apiFetch<{ roles: AdminRole[] }>('/admin/rbac/roles', {}, token),
      apiFetch<{ permissions: AdminPermission[] }>('/admin/rbac/permissions', {}, token)
    ])
      .then(([rolesResponse, permissionsResponse]) => {
        setRoles(rolesResponse.roles ?? []);
        setPermissions(permissionsResponse.permissions ?? []);
      })
      .catch((error) => showToast(error instanceof Error ? error.message : 'Не удалось загрузить роли'))
      .finally(() => setLoading(false));
  }, [showToast, token, user?.canManageRoles]);

  function openCreateDialog() {
    setEditingRole(null);
    setForm(emptyForm);
    setDialogOpen(true);
  }

  function openEditDialog(role: AdminRole) {
    setEditingRole(role);
    setForm({
      slug: role.slug,
      name: role.name,
      description: role.description ?? '',
      permissionSlugs: role.permissions.map((permission) => permission.slug)
    });
    setDialogOpen(true);
  }

  async function handleSaveRole() {
    if (!token) return;
    setSaving(true);
    try {
      if (editingRole) {
        await apiFetch(`/admin/rbac/roles/${editingRole.slug}`, {
          method: 'PATCH',
          body: JSON.stringify({
            name: form.name,
            description: form.description || undefined,
            permissionSlugs: form.permissionSlugs
          })
        }, token);
        showToast('Роль обновлена');
      } else {
        await apiFetch('/admin/rbac/roles', {
          method: 'POST',
          body: JSON.stringify(form)
        }, token);
        showToast('Роль создана');
      }
      setDialogOpen(false);
      setForm(emptyForm);
      setEditingRole(null);
      await reloadRoles();
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось сохранить роль');
    } finally {
      setSaving(false);
    }
  }

  async function handleDeleteRole(role: AdminRole) {
    if (!token || role.isSystem) return;
    if (!window.confirm(`Удалить роль «${role.name}»? Она будет снята со всех пользователей.`)) return;
    setSaving(true);
    try {
      await apiFetch(`/admin/rbac/roles/${role.slug}`, { method: 'DELETE' }, token);
      showToast('Роль удалена');
      await reloadRoles();
    } catch (error) {
      showToast(error instanceof Error ? error.message : 'Не удалось удалить роль');
    } finally {
      setSaving(false);
    }
  }

  if (!user?.canManageRoles) {
    return (
      <AdminShell active="/admin/rbac">
        <p className="text-[#667085]">Управление ролями доступно пользователям с правом rbac.manage.</p>
      </AdminShell>
    );
  }

  return (
    <AdminShell active="/admin/rbac">
      <div className="mb-6 flex items-center justify-between gap-4">
        <div>
          <h2 className="text-2xl font-medium">Роли и права</h2>
          <p className="text-sm text-[#667085]">Редактируйте роли, назначайте права всем пользователям или отдельным аккаунтам</p>
        </div>
        <Button onClick={openCreateDialog}>
          <Plus className="h-4 w-4" />
          Создать роль
        </Button>
      </div>

      {loading ? (
        <div className="flex items-center justify-center gap-2 py-16 text-[#667085]">
          <Loader2 className="h-5 w-5 animate-spin" />
          Загрузка...
        </div>
      ) : (
        <div className="grid gap-4 md:grid-cols-3">
          {roles.map((role) => (
            <Card key={role.id} className="bg-[#f8f9fb] shadow-none">
              <CardHeader>
                <div className="flex items-start justify-between gap-2">
                  <ShieldCheck className="h-6 w-6 shrink-0" />
                  <div className="flex gap-1">
                    <Button variant="ghost" size="icon" aria-label="Редактировать роль" onClick={() => openEditDialog(role)}>
                      <Pencil className="h-4 w-4" />
                    </Button>
                    {!role.isSystem ? (
                      <Button variant="ghost" size="icon" aria-label="Удалить роль" disabled={saving} onClick={() => void handleDeleteRole(role)}>
                        <Trash2 className="h-4 w-4 text-red-600" />
                      </Button>
                    ) : null}
                  </div>
                </div>
                <CardTitle>{role.name}</CardTitle>
                <CardDescription>
                  {role.permissions.length} прав · {role.slug}
                  {role.isSystem ? ' · системная' : ''}
                  {role.isDefault ? ' · по умолчанию' : ''}
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-2">
                {role.permissions.length ? (
                  role.permissions.map((permission) => (
                    <div key={permission.id} className="rounded-xl bg-white px-3 py-2 text-sm">
                      <div className="font-medium">{permission.name}</div>
                      <div className="text-xs text-[#667085]">{permission.slug}</div>
                    </div>
                  ))
                ) : (
                  <p className="text-sm text-[#667085]">Права не назначены</p>
                )}
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editingRole ? `Редактирование: ${editingRole.name}` : 'Новая роль'}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            {!editingRole ? (
              <Input value={form.slug} onChange={(event) => setForm((current) => ({ ...current, slug: event.target.value }))} placeholder="slug, например support" />
            ) : (
              <p className="rounded-xl bg-[#f4f5f8] px-3 py-2 text-sm text-[#667085]">Slug: {editingRole.slug}</p>
            )}
            <Input value={form.name} onChange={(event) => setForm((current) => ({ ...current, name: event.target.value }))} placeholder="Название роли" />
            <Input value={form.description} onChange={(event) => setForm((current) => ({ ...current, description: event.target.value }))} placeholder="Описание" />
            <div className="space-y-2">
              <p className="text-sm font-medium">Права</p>
              {permissions.map((permission) => (
                <label key={permission.id} className="flex items-center gap-2 rounded-xl bg-[#f4f5f8] px-3 py-2 text-sm">
                  <input
                    type="checkbox"
                    checked={form.permissionSlugs.includes(permission.slug)}
                    onChange={(event) =>
                      setForm((current) => ({
                        ...current,
                        permissionSlugs: event.target.checked
                          ? [...current.permissionSlugs, permission.slug]
                          : current.permissionSlugs.filter((item) => item !== permission.slug)
                      }))
                    }
                  />
                  <span>{permission.name}</span>
                </label>
              ))}
            </div>
            <Button className="w-full" disabled={saving || !form.name.trim() || (!editingRole && !form.slug.trim())} onClick={() => void handleSaveRole()}>
              {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : editingRole ? 'Сохранить изменения' : 'Создать роль'}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </AdminShell>
  );
}
