'use client';

import type { TicketDashboard, TicketPriority } from '@nexumi/shared';
import { ExternalLink, RefreshCw } 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 { Badge, type BadgeProps } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';

const STATUS_VARIANTS: Record<'OPEN' | 'CLAIMED', BadgeProps['variant']> = {
  OPEN: 'secondary',
  CLAIMED: 'success'
};

const PRIORITY_VARIANTS: Record<TicketPriority, BadgeProps['variant']> = {
  LOW: 'outline',
  NORMAL: 'secondary',
  HIGH: 'default',
  URGENT: 'destructive'
};

const PRIORITIES: TicketPriority[] = ['LOW', 'NORMAL', 'HIGH', 'URGENT'];

function formatDate(iso: string): string {
  return new Date(iso).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' });
}

function discordChannelUrl(guildId: string, ticket: TicketDashboard): string | null {
  const channelId = ticket.channelId ?? ticket.threadId;
  if (!channelId) {
    return null;
  }
  return `https://discord.com/channels/${guildId}/${channelId}`;
}

interface OpenTicketsManagerProps {
  guildId: string;
  initialTickets: TicketDashboard[];
}

export function OpenTicketsManager({ guildId, initialTickets }: OpenTicketsManagerProps) {
  const t = useTranslations();
  const [tickets, setTickets] = useState<TicketDashboard[]>(initialTickets);
  const [pendingId, setPendingId] = useState<string | null>(null);
  const [reasons, setReasons] = useState<Record<string, string>>({});
  const [loading, setLoading] = useState(false);

  async function reload() {
    setLoading(true);
    try {
      const response = await fetch(`/api/guilds/${guildId}/tickets/open`);
      const body = (await response.json().catch(() => null)) as { tickets?: TicketDashboard[] } | null;
      if (response.ok && body?.tickets) {
        setTickets(body.tickets);
      } else {
        toast.error(t('common.saveError'));
      }
    } catch {
      toast.error(t('common.networkError'));
    } finally {
      setLoading(false);
    }
  }

  async function runAction(
    ticket: TicketDashboard,
    payload:
      | { action: 'close'; reason?: string }
      | { action: 'claim' }
      | { action: 'priority'; priority: TicketPriority }
  ) {
    setPendingId(ticket.id);
    try {
      const response = await fetch(`/api/guilds/${guildId}/tickets/open/${ticket.id}/action`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      const body = (await response.json().catch(() => null)) as
        | (TicketDashboard & { error?: string })
        | null;
      if (!response.ok || !body) {
        toast.error(body?.error ?? t('common.saveError'));
        return;
      }

      if (payload.action === 'close') {
        setTickets((prev) => prev.filter((entry) => entry.id !== ticket.id));
        toast.success(t('modulePages.tickets.openList.closed'));
      } else {
        setTickets((prev) => prev.map((entry) => (entry.id === ticket.id ? body : entry)));
        toast.success(t('common.saveSuccess'));
      }
    } catch {
      toast.error(t('common.networkError'));
    } finally {
      setPendingId(null);
    }
  }

  return (
    <FieldAnchor id="field-tickets-open">
      <Card>
        <CardHeader className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <CardTitle>{t('modulePages.tickets.openList.title')}</CardTitle>
            <CardDescription>{t('modulePages.tickets.openList.description')}</CardDescription>
          </div>
          <Button type="button" variant="outline" size="sm" onClick={reload} disabled={loading}>
            <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />
            {t('modulePages.tickets.openList.refresh')}
          </Button>
        </CardHeader>
        <CardContent className="space-y-3">
          {!loading && tickets.length === 0 && (
            <p className="text-sm text-muted-foreground">{t('modulePages.tickets.openList.empty')}</p>
          )}
          {tickets.map((ticket) => {
            const channelUrl = discordChannelUrl(guildId, ticket);
            const busy = pendingId === ticket.id;
            const statusKey = ticket.status === 'CLAIMED' ? 'CLAIMED' : 'OPEN';

            return (
              <div key={ticket.id} className="space-y-3 rounded-md border border-border p-4">
                <div className="flex flex-wrap items-start justify-between gap-2">
                  <div className="min-w-0 space-y-1">
                    <p className="font-medium">
                      {ticket.subject?.trim() || t('modulePages.tickets.openList.noSubject')}
                    </p>
                    <p className="text-xs text-muted-foreground">
                      {ticket.categoryName
                        ? t('modulePages.tickets.openList.categoryLine', {
                            category: ticket.categoryName
                          })
                        : t('modulePages.tickets.openList.noCategory')}
                      {' · '}
                      &lt;@{ticket.openerId}&gt;
                      {ticket.claimedById ? (
                        <>
                          {' · '}
                          {t('modulePages.tickets.openList.claimedBy', {
                            user: `<@${ticket.claimedById}>`
                          })}
                        </>
                      ) : null}
                      {' · '}
                      {formatDate(ticket.lastActivityAt)}
                    </p>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    <Badge variant={STATUS_VARIANTS[statusKey]}>
                      {t(`modulePages.tickets.openList.status.${statusKey}`)}
                    </Badge>
                    <Badge variant={PRIORITY_VARIANTS[ticket.priority]}>
                      {t(`modulePages.tickets.openList.priority.${ticket.priority}`)}
                    </Badge>
                  </div>
                </div>

                <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                  <Input
                    className="sm:max-w-xs"
                    placeholder={t('modulePages.tickets.openList.closeReasonPlaceholder')}
                    value={reasons[ticket.id] ?? ''}
                    disabled={busy}
                    onChange={(event) =>
                      setReasons((prev) => ({ ...prev, [ticket.id]: event.target.value }))
                    }
                  />
                  <div className="flex flex-wrap gap-2">
                    {channelUrl ? (
                      <Button type="button" variant="outline" size="sm" asChild>
                        <a href={channelUrl} target="_blank" rel="noreferrer">
                          <ExternalLink className="size-4" />
                          {t('modulePages.tickets.openList.openInDiscord')}
                        </a>
                      </Button>
                    ) : null}
                    <Button
                      type="button"
                      variant="secondary"
                      size="sm"
                      disabled={busy}
                      onClick={() => runAction(ticket, { action: 'claim' })}
                    >
                      {t('modulePages.tickets.openList.claim')}
                    </Button>
                    <Button
                      type="button"
                      variant="destructive"
                      size="sm"
                      disabled={busy}
                      onClick={() =>
                        runAction(ticket, {
                          action: 'close',
                          reason: reasons[ticket.id]?.trim() || undefined
                        })
                      }
                    >
                      {t('modulePages.tickets.openList.close')}
                    </Button>
                    <Select
                      value={ticket.priority}
                      disabled={busy}
                      onValueChange={(priority) =>
                        runAction(ticket, {
                          action: 'priority',
                          priority: priority as TicketPriority
                        })
                      }
                    >
                      <SelectTrigger className="w-40">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {PRIORITIES.map((priority) => (
                          <SelectItem key={priority} value={priority}>
                            {t(`modulePages.tickets.openList.priority.${priority}`)}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              </div>
            );
          })}
        </CardContent>
      </Card>
    </FieldAnchor>
  );
}
