'use client';

import type { TicketCategoryDashboard } from '@nexumi/shared';
import { Plus, Trash2 } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import { FieldAnchor } from '@/components/layout/field-anchor';
import { useTranslations } from '@/components/locale-provider';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { DiscordEmojiSelect } from '@/components/ui/discord-emoji-select';
import { DiscordRoleMultiSelect } from '@/components/ui/discord-role-select';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

interface LocalCategory extends TicketCategoryDashboard {
  clientKey: string;
  saving?: boolean;
}

const EMPTY_DRAFT = { name: '', description: '', emoji: '', supportRoleIds: [] as string[] };

interface TicketCategoriesManagerProps {
  guildId: string;
  initialCategories: TicketCategoryDashboard[];
}

function panelSyncErrorMessage(
  code: string | undefined,
  fallback: string | undefined,
  t: (key: string) => string
): string {
  if (code === 'timeout') {
    return t('modulePages.tickets.errors.panelTimeout');
  }
  if (code === 'no_categories') {
    return t('modulePages.tickets.errors.noCategories');
  }
  if (code === 'not_posted') {
    return t('modulePages.tickets.errors.panelNotPosted');
  }
  return fallback ?? t('common.saveError');
}

export function TicketCategoriesManager({ guildId, initialCategories }: TicketCategoriesManagerProps) {
  const t = useTranslations();
  const [categories, setCategories] = useState<LocalCategory[]>(
    initialCategories.map((category, index) => ({ ...category, clientKey: category.id ?? `existing-${index}` }))
  );
  const [draft, setDraft] = useState(EMPTY_DRAFT);
  const [creating, setCreating] = useState(false);

  async function handleCreate() {
    if (!draft.name.trim()) {
      toast.error(t('modulePages.tickets.nameRequired'));
      return;
    }
    setCreating(true);
    try {
      const response = await fetch(`/api/guilds/${guildId}/tickets/categories`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: draft.name.trim(),
          description: draft.description.trim() || null,
          emoji: draft.emoji.trim() || null,
          supportRoleIds: draft.supportRoleIds
        })
      });
      const body = (await response.json().catch(() => null)) as
        | (TicketCategoryDashboard & { error?: string; code?: string })
        | null;
      if (!response.ok || !body) {
        toast.error(panelSyncErrorMessage(body?.code, body?.error, t));
        return;
      }
      setCategories((prev) => [...prev, { ...body, clientKey: body.id ?? `new-${Date.now()}` }]);
      setDraft(EMPTY_DRAFT);
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    } finally {
      setCreating(false);
    }
  }

  async function handleSaveRow(category: LocalCategory) {
    setCategories((prev) =>
      prev.map((entry) => (entry.clientKey === category.clientKey ? { ...entry, saving: true } : entry))
    );
    try {
      const response = await fetch(`/api/guilds/${guildId}/tickets/categories/${category.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: category.name,
          description: category.description?.trim() ? category.description : null,
          emoji: category.emoji?.trim() ? category.emoji : null,
          supportRoleIds: category.supportRoleIds
        })
      });
      const body = (await response.json().catch(() => null)) as
        | (TicketCategoryDashboard & { error?: string; code?: string })
        | null;
      if (!response.ok || !body || !body.id) {
        toast.error(panelSyncErrorMessage(body?.code, body?.error, t));
        return;
      }
      setCategories((prev) =>
        prev.map((entry) =>
          entry.clientKey === category.clientKey
            ? { ...body, clientKey: entry.clientKey, saving: false }
            : entry
        )
      );
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    } finally {
      setCategories((prev) =>
        prev.map((entry) => (entry.clientKey === category.clientKey ? { ...entry, saving: false } : entry))
      );
    }
  }

  async function handleDelete(category: LocalCategory) {
    try {
      const response = await fetch(`/api/guilds/${guildId}/tickets/categories/${category.id}`, {
        method: 'DELETE'
      });
      if (!response.ok) {
        const body = (await response.json().catch(() => null)) as { error?: string; code?: string } | null;
        toast.error(panelSyncErrorMessage(body?.code, body?.error, t));
        return;
      }
      setCategories((prev) => prev.filter((entry) => entry.clientKey !== category.clientKey));
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    }
  }

  return (
    <FieldAnchor id="field-tickets-categories">
    <Card>
      <CardHeader>
        <CardTitle>{t('modulePages.tickets.categoriesTitle')}</CardTitle>
        <CardDescription>{t('modulePages.tickets.categoriesDescription')}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {categories.length === 0 && (
          <p className="text-sm text-muted-foreground">{t('modulePages.tickets.categoriesEmpty')}</p>
        )}
        {categories.map((category) => (
          <div key={category.clientKey} className="space-y-3 rounded-md border border-border p-4">
            <div className="grid gap-3 sm:grid-cols-4">
              <div className="space-y-2">
                <Label>{t('modulePages.tickets.categoryName')}</Label>
                <Input
                  value={category.name}
                  onChange={(event) =>
                    setCategories((prev) =>
                      prev.map((entry) =>
                        entry.clientKey === category.clientKey ? { ...entry, name: event.target.value } : entry
                      )
                    )
                  }
                />
              </div>
              <div className="space-y-2">
                <Label>{t('modulePages.tickets.categoryEmoji')}</Label>
                <DiscordEmojiSelect
                  guildId={guildId}
                  value={category.emoji ?? undefined}
                  onChange={(emoji) =>
                    setCategories((prev) =>
                      prev.map((entry) =>
                        entry.clientKey === category.clientKey
                          ? { ...entry, emoji: emoji ?? null }
                          : entry
                      )
                    )
                  }
                />
              </div>
              <div className="col-span-2 space-y-2">
                <Label>{t('modulePages.tickets.categoryDescription')}</Label>
                <Input
                  value={category.description ?? ''}
                  onChange={(event) =>
                    setCategories((prev) =>
                      prev.map((entry) =>
                        entry.clientKey === category.clientKey
                          ? { ...entry, description: event.target.value }
                          : entry
                      )
                    )
                  }
                />
              </div>
            </div>
            <div className="space-y-2">
              <Label>{t('modulePages.tickets.supportRoleIds')}</Label>
              <DiscordRoleMultiSelect
                guildId={guildId}
                value={category.supportRoleIds}
                onChange={(supportRoleIds) =>
                  setCategories((prev) =>
                    prev.map((entry) =>
                      entry.clientKey === category.clientKey ? { ...entry, supportRoleIds } : entry
                    )
                  )
                }
              />
            </div>
            <div className="flex justify-end gap-2">
              <Button type="button" variant="outline" onClick={() => handleSaveRow(category)} disabled={category.saving}>
                {category.saving ? t('common.saving') : t('common.save')}
              </Button>
              <Button type="button" variant="ghost" size="icon" aria-label={t('common.remove')} onClick={() => handleDelete(category)}>
                <Trash2 className="size-4" />
              </Button>
            </div>
          </div>
        ))}

        <div className="space-y-3 rounded-md border border-dashed border-border p-4">
          <p className="text-sm font-medium">{t('modulePages.tickets.addCategory')}</p>
          <div className="grid gap-3 sm:grid-cols-4">
            <div className="space-y-2">
              <Label>{t('modulePages.tickets.categoryName')}</Label>
              <Input value={draft.name} onChange={(event) => setDraft((prev) => ({ ...prev, name: event.target.value }))} />
            </div>
            <div className="space-y-2">
              <Label>{t('modulePages.tickets.categoryEmoji')}</Label>
              <DiscordEmojiSelect
                guildId={guildId}
                value={draft.emoji || undefined}
                onChange={(emoji) => setDraft((prev) => ({ ...prev, emoji: emoji ?? '' }))}
              />
            </div>
            <div className="col-span-2 space-y-2">
              <Label>{t('modulePages.tickets.categoryDescription')}</Label>
              <Input
                value={draft.description}
                onChange={(event) => setDraft((prev) => ({ ...prev, description: event.target.value }))}
              />
            </div>
          </div>
          <div className="space-y-2">
            <Label>{t('modulePages.tickets.supportRoleIds')}</Label>
            <DiscordRoleMultiSelect
              guildId={guildId}
              value={draft.supportRoleIds}
              onChange={(supportRoleIds) => setDraft((prev) => ({ ...prev, supportRoleIds }))}
            />
          </div>
          <Button type="button" variant="outline" onClick={handleCreate} disabled={creating}>
            <Plus className="size-4" />
            {t('modulePages.tickets.addCategory')}
          </Button>
        </div>
      </CardContent>
    </Card>
    </FieldAnchor>
  );
}
