'use client';

import { EmptyState } from '@/components/entity-list';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Role } from '@hed-hog/api-types';
import { useApp, useQuery } from '@hed-hog/next-app-provider';
import { Eye, Loader2, Search, ShieldCheck } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { toast } from 'sonner';
import { UserAccessSheet } from './user-access-sheet';

type CustomRole = Role & {
  isAssigned: boolean;
};

type PermissionsSectionProps = {
  userId: number;
  userName?: string;
  onRoleChange?: () => void;
};

export function PermissionsSection({
  userId,
  userName,
  onRoleChange,
}: PermissionsSectionProps) {
  const t = useTranslations('core.UserPage');
  const { request, currentLocaleCode } = useApp();
  const [togglingRoleId, setTogglingRoleId] = useState<number | null>(null);
  const [search, setSearch] = useState('');
  const [accessSheetOpen, setAccessSheetOpen] = useState(false);

  const {
    data: userRoles = [],
    isLoading: isLoadingUserRoles,
    refetch: refetchUserRoles,
  } = useQuery<CustomRole[]>({
    queryKey: ['user-roles', userId, currentLocaleCode],
    queryFn: async () => {
      const response = await request<CustomRole[]>({
        url: `/user/${userId}/role`,
        method: 'GET',
      });
      return response.data || [];
    },
    enabled: !!userId,
  });

  const handleToggleRole = async (roleId: number, isAssigned: boolean) => {
    setTogglingRoleId(roleId);
    try {
      if (isAssigned) {
        await request({
          url: `/user/${userId}/role/${roleId}`,
          method: 'DELETE',
        });
        toast.success(t('roleRemoved'));
      } else {
        await request({
          url: `/user/${userId}/role/${roleId}`,
          method: 'POST',
        });
        toast.success(t('roleAssigned'));
      }
      await refetchUserRoles();
      onRoleChange?.();
    } catch {
      toast.error(
        isAssigned ? t('errorRemovingRole') : t('errorAssigningRole')
      );
    } finally {
      setTogglingRoleId(null);
    }
  };

  const filteredRoles = userRoles.filter((role) => {
    if (!search.trim()) return true;
    const q = search.toLowerCase();
    return (
      role.name?.toLowerCase().includes(q) ||
      role.slug?.toLowerCase().includes(q) ||
      role.description?.toLowerCase().includes(q)
    );
  });

  if (isLoadingUserRoles) {
    return (
      <div className="flex items-center justify-center py-8">
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
        <span className="ml-2 text-sm text-muted-foreground">
          {t('loadingRoles')}
        </span>
      </div>
    );
  }

  if (!userRoles || userRoles.length === 0) {
    return (
      <EmptyState
        className="min-h-60 py-10"
        icon={<ShieldCheck className="h-12 w-12" />}
        title={t('noRolesAvailable')}
      />
    );
  }

  return (
    <>
      <div className="flex items-center gap-2 mb-3">
        <div className="relative flex-1">
          <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
          <Input
            placeholder={t('filterRolesPlaceholder')}
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="pl-8 h-8 text-sm"
          />
        </div>
        <Button
          variant="outline"
          size="sm"
          className="shrink-0 gap-1.5"
          onClick={() => setAccessSheetOpen(true)}
        >
          <Eye className="h-4 w-4" />
          {t('viewAccessButton')}
        </Button>
      </div>

      {filteredRoles.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-10 text-center">
          <Search className="h-8 w-8 text-muted-foreground/40 mb-2" />
          <p className="text-sm text-muted-foreground">{t('noRolesMatch')}</p>
        </div>
      ) : (
        <div className="space-y-2">
          {filteredRoles.map((role, index) => {
            const isToggling = togglingRoleId === role.id;

            return (
              <Card
                key={role.id ?? `role-${index}`}
                className={`transition-all py-4 ${
                  role.isAssigned
                    ? 'border-primary bg-primary/5'
                    : 'border-border hover:border-primary/50'
                }`}
              >
                <CardContent className="flex items-center justify-between px-4">
                  <div className="flex items-center gap-2 flex-1">
                    <div
                      className={`rounded-md p-2 ${
                        role.isAssigned ? 'bg-primary/10' : 'bg-muted'
                      }`}
                    >
                      <ShieldCheck
                        className={`h-5 w-5 ${
                          role.isAssigned
                            ? 'text-primary'
                            : 'text-muted-foreground'
                        }`}
                      />
                    </div>
                    <div className="flex-1">
                      <Label
                        htmlFor={`role-${role.id}`}
                        className="text-sm font-medium cursor-pointer"
                      >
                        {role.name} ({role.slug})
                      </Label>
                      {role.description && (
                        <p className="text-xs text-muted-foreground">
                          {role.description}
                        </p>
                      )}
                    </div>
                  </div>
                  <Switch
                    id={`role-${role.id}`}
                    checked={role.isAssigned}
                    disabled={isToggling}
                    onCheckedChange={() =>
                      handleToggleRole(role.id!, role.isAssigned)
                    }
                    className="ml-4"
                  />
                </CardContent>
              </Card>
            );
          })}
        </div>
      )}

      <UserAccessSheet
        open={accessSheetOpen}
        onOpenChange={setAccessSheetOpen}
        userId={userId}
        userName={userName}
      />
    </>
  );
}
