'use client';

import type { SelfRoleBehavior, SelfRoleMode, SelfRolePanelDashboard } 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 { DiscordChannelSelect } from '@/components/ui/discord-channel-select';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  builderRowsToRoles,
  emptyBuilderRow,
  rolesToBuilderRows,
  type SelfRoleBuilderRow,
  SelfRoleEntriesBuilder
} from '@/components/ui/self-role-entries-builder';

const MODES: SelfRoleMode[] = ['BUTTONS', 'DROPDOWN', 'REACTIONS'];
const BEHAVIORS: SelfRoleBehavior[] = ['NORMAL', 'UNIQUE', 'VERIFY', 'TEMPORARY'];

interface LocalPanel extends Omit<SelfRolePanelDashboard, 'roles'> {
  clientKey: string;
  roles: SelfRoleBuilderRow[];
  saving?: boolean;
}

const EMPTY_DRAFT = {
  channelId: '',
  title: '',
  description: '',
  mode: 'BUTTONS' as SelfRoleMode,
  behavior: 'NORMAL' as SelfRoleBehavior,
  roles: [emptyBuilderRow()] as SelfRoleBuilderRow[]
};

interface SelfRolesManagerProps {
  guildId: string;
  initialPanels: SelfRolePanelDashboard[];
}

function toastBuilderError(
  t: ReturnType<typeof useTranslations>,
  error: 'incomplete' | 'emojiRequired' | 'tooMany'
) {
  if (error === 'emojiRequired') {
    toast.error(t('modulePages.selfroles.emojiRequired'));
    return;
  }
  if (error === 'tooMany') {
    toast.error(t('modulePages.selfroles.tooManyRoles'));
    return;
  }
  toast.error(t('modulePages.selfroles.formIncomplete'));
}

export function SelfRolesManager({ guildId, initialPanels }: SelfRolesManagerProps) {
  const t = useTranslations();
  const [panels, setPanels] = useState<LocalPanel[]>(
    initialPanels.map((panel, index) => ({
      ...panel,
      clientKey: panel.id ?? `existing-${index}`,
      roles: rolesToBuilderRows(panel.roles)
    }))
  );
  const [draft, setDraft] = useState(EMPTY_DRAFT);
  const [creating, setCreating] = useState(false);

  async function handleCreate() {
    if (!draft.channelId.trim() || !draft.title.trim()) {
      toast.error(t('modulePages.selfroles.formIncomplete'));
      return;
    }
    const parsed = builderRowsToRoles(draft.roles, draft.mode === 'REACTIONS');
    if (parsed.error || !parsed.value.length) {
      toastBuilderError(t, parsed.error ?? 'incomplete');
      return;
    }
    setCreating(true);
    try {
      const response = await fetch(`/api/guilds/${guildId}/selfroles`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          channelId: draft.channelId.trim(),
          title: draft.title.trim(),
          description: draft.description.trim() || null,
          mode: draft.mode,
          behavior: draft.behavior,
          roles: parsed.value
        })
      });
      const body = (await response.json().catch(() => null)) as (SelfRolePanelDashboard & { error?: string }) | null;
      if (!response.ok || !body) {
        toast.error(body?.error ?? t('common.saveError'));
        return;
      }
      setPanels((prev) => [
        {
          ...body,
          clientKey: body.id ?? `new-${Date.now()}`,
          roles: rolesToBuilderRows(body.roles)
        },
        ...prev
      ]);
      setDraft({ ...EMPTY_DRAFT, roles: [emptyBuilderRow()] });
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    } finally {
      setCreating(false);
    }
  }

  async function handleSave(panel: LocalPanel) {
    if (!panel.id) {
      return;
    }
    const parsed = builderRowsToRoles(panel.roles, panel.mode === 'REACTIONS');
    if (parsed.error || !parsed.value.length) {
      toastBuilderError(t, parsed.error ?? 'incomplete');
      return;
    }
    setPanels((prev) => prev.map((entry) => (entry.clientKey === panel.clientKey ? { ...entry, saving: true } : entry)));
    try {
      const response = await fetch(`/api/guilds/${guildId}/selfroles/${panel.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          channelId: panel.channelId,
          title: panel.title,
          description: panel.description,
          mode: panel.mode,
          behavior: panel.behavior,
          roles: parsed.value
        })
      });
      const body = (await response.json().catch(() => null)) as (SelfRolePanelDashboard & { error?: string }) | null;
      if (!response.ok || !body) {
        toast.error(body?.error ?? t('common.saveError'));
        return;
      }
      setPanels((prev) =>
        prev.map((entry) =>
          entry.clientKey === panel.clientKey
            ? {
                ...entry,
                ...body,
                roles: rolesToBuilderRows(body.roles),
                saving: false
              }
            : entry
        )
      );
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    } finally {
      setPanels((prev) =>
        prev.map((entry) => (entry.clientKey === panel.clientKey ? { ...entry, saving: false } : entry))
      );
    }
  }

  async function handleDelete(panel: LocalPanel) {
    if (!window.confirm(t('modulePages.selfroles.confirmDelete'))) {
      return;
    }
    try {
      const response = await fetch(`/api/guilds/${guildId}/selfroles/${panel.id}`, { method: 'DELETE' });
      if (!response.ok) {
        toast.error(t('common.saveError'));
        return;
      }
      setPanels((prev) => prev.filter((entry) => entry.clientKey !== panel.clientKey));
      toast.success(t('common.saveSuccess'));
    } catch {
      toast.error(t('common.saveError'));
    }
  }

  return (
    <div className="space-y-6">
      <FieldAnchor id="field-selfroles-create">
        <Card>
          <CardHeader>
            <CardTitle>{t('modulePages.selfroles.createTitle')}</CardTitle>
            <CardDescription>{t('modulePages.selfroles.createDescription')}</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <Label>{t('modulePages.selfroles.channelId')}</Label>
                <DiscordChannelSelect
                  guildId={guildId}
                  value={draft.channelId}
                  onChange={(channelId) => setDraft((prev) => ({ ...prev, channelId }))}
                />
              </div>
              <div className="space-y-2">
                <Label>{t('modulePages.selfroles.panelTitle')}</Label>
                <Input
                  value={draft.title}
                  onChange={(event) => setDraft((prev) => ({ ...prev, title: event.target.value }))}
                />
              </div>
              <div className="space-y-2">
                <Label>{t('modulePages.selfroles.mode')}</Label>
                <Select
                  value={draft.mode}
                  onValueChange={(mode) => setDraft((prev) => ({ ...prev, mode: mode as SelfRoleMode }))}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {MODES.map((mode) => (
                      <SelectItem key={mode} value={mode}>
                        {t(`modulePages.selfroles.modes.${mode}`)}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label>{t('modulePages.selfroles.behavior')}</Label>
                <Select
                  value={draft.behavior}
                  onValueChange={(behavior) =>
                    setDraft((prev) => ({ ...prev, behavior: behavior as SelfRoleBehavior }))
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {BEHAVIORS.map((behavior) => (
                      <SelectItem key={behavior} value={behavior}>
                        {t(`modulePages.selfroles.behaviors.${behavior}`)}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
            <div className="space-y-2">
              <Label>{t('modulePages.selfroles.description')}</Label>
              <Input
                value={draft.description}
                onChange={(event) => setDraft((prev) => ({ ...prev, description: event.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>{t('modulePages.selfroles.roles')}</Label>
              <SelfRoleEntriesBuilder
                guildId={guildId}
                value={draft.roles}
                requireEmoji={draft.mode === 'REACTIONS'}
                onChange={(roles) => setDraft((prev) => ({ ...prev, roles }))}
              />
            </div>
            <Button type="button" onClick={handleCreate} disabled={creating}>
              <Plus className="size-4" />
              {creating ? t('common.saving') : t('modulePages.selfroles.create')}
            </Button>
          </CardContent>
        </Card>
      </FieldAnchor>

      <FieldAnchor id="field-selfroles-list">
        <Card>
          <CardHeader>
            <CardTitle>{t('modulePages.selfroles.listTitle')}</CardTitle>
            <CardDescription>{t('modulePages.selfroles.listDescription')}</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            {panels.length === 0 && (
              <p className="text-sm text-muted-foreground">{t('modulePages.selfroles.empty')}</p>
            )}
            {panels.map((panel) => (
              <div key={panel.clientKey} className="space-y-3 rounded-md border border-border p-4">
                <div className="grid gap-3 sm:grid-cols-2">
                  <div className="space-y-2">
                    <Label>{t('modulePages.selfroles.channelId')}</Label>
                    <DiscordChannelSelect
                      guildId={guildId}
                      value={panel.channelId}
                      onChange={(channelId) =>
                        setPanels((prev) =>
                          prev.map((entry) =>
                            entry.clientKey === panel.clientKey ? { ...entry, channelId } : entry
                          )
                        )
                      }
                    />
                  </div>
                  <div className="space-y-2">
                    <Label>{t('modulePages.selfroles.panelTitle')}</Label>
                    <Input
                      value={panel.title}
                      onChange={(event) =>
                        setPanels((prev) =>
                          prev.map((entry) =>
                            entry.clientKey === panel.clientKey
                              ? { ...entry, title: event.target.value }
                              : entry
                          )
                        )
                      }
                    />
                  </div>
                  <div className="space-y-2">
                    <Label>{t('modulePages.selfroles.mode')}</Label>
                    <Select
                      value={panel.mode}
                      onValueChange={(mode) =>
                        setPanels((prev) =>
                          prev.map((entry) =>
                            entry.clientKey === panel.clientKey
                              ? { ...entry, mode: mode as SelfRoleMode }
                              : entry
                          )
                        )
                      }
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {MODES.map((mode) => (
                          <SelectItem key={mode} value={mode}>
                            {t(`modulePages.selfroles.modes.${mode}`)}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="space-y-2">
                    <Label>{t('modulePages.selfroles.behavior')}</Label>
                    <Select
                      value={panel.behavior}
                      onValueChange={(behavior) =>
                        setPanels((prev) =>
                          prev.map((entry) =>
                            entry.clientKey === panel.clientKey
                              ? { ...entry, behavior: behavior as SelfRoleBehavior }
                              : entry
                          )
                        )
                      }
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {BEHAVIORS.map((behavior) => (
                          <SelectItem key={behavior} value={behavior}>
                            {t(`modulePages.selfroles.behaviors.${behavior}`)}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
                <div className="space-y-2">
                  <Label>{t('modulePages.selfroles.roles')}</Label>
                  <SelfRoleEntriesBuilder
                    guildId={guildId}
                    value={panel.roles}
                    requireEmoji={panel.mode === 'REACTIONS'}
                    disabled={panel.saving}
                    onChange={(roles) =>
                      setPanels((prev) =>
                        prev.map((entry) =>
                          entry.clientKey === panel.clientKey ? { ...entry, roles } : entry
                        )
                      )
                    }
                  />
                </div>
                <div className="flex justify-end gap-2">
                  <Button type="button" variant="outline" disabled={panel.saving} onClick={() => handleSave(panel)}>
                    {panel.saving ? t('common.saving') : t('common.save')}
                  </Button>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    aria-label={t('common.remove')}
                    onClick={() => handleDelete(panel)}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </div>
              </div>
            ))}
          </CardContent>
        </Card>
      </FieldAnchor>
    </div>
  );
}
