"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { CheckCheck, Loader2, RotateCcw, XCircle } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import {
  adminAssignTicketAction,
  adminCloseTicketAction,
  adminMarkTicketUnreadAction,
  adminReopenTicketAction,
  type AdminTicketActionState,
} from "@/lib/actions/admin-tickets";
import { adminTicketsTexts as tx } from "@/lib/i18n/admin-tickets";
import type { AdminTicketAssigneeOption, AdminTicketStatusValue } from "./types";

function report(result: AdminTicketActionState) {
  if (result && result.ok === false) toast.error(result.error);
}

/** Assignee dropdown — saves as soon as it changes. */
export function AdminTicketAssignSelect({
  ticketId,
  assigneeId,
  options,
}: {
  ticketId: string;
  assigneeId: string | null;
  options: AdminTicketAssigneeOption[];
}) {
  const [value, setValue] = React.useState(assigneeId ?? "");
  const [pending, startTransition] = React.useTransition();

  React.useEffect(() => setValue(assigneeId ?? ""), [assigneeId]);

  function change(next: string) {
    setValue(next);
    const data = new FormData();
    data.set("id", ticketId);
    data.set("assigneeId", next);
    startTransition(async () => {
      report(await adminAssignTicketAction(data));
    });
  }

  return (
    <div className="flex items-center gap-1.5">
      <NativeSelect
        size="sm"
        aria-label={tx.detail.assignee}
        value={value}
        disabled={pending}
        onChange={(e) => change(e.target.value)}
        className="w-full"
      >
        <NativeSelectOption value="">{tx.filters.unassigned}</NativeSelectOption>
        {options.map((o) => (
          <NativeSelectOption key={o.id} value={o.id}>
            {o.username} · {o.role}
          </NativeSelectOption>
        ))}
      </NativeSelect>
      {pending ? (
        <Loader2 className="size-3.5 shrink-0 animate-spin text-muted-foreground" />
      ) : null}
    </div>
  );
}

/** Close / Reopen pair plus a "mark unread" escape hatch. */
export function AdminTicketStatusButtons({
  ticketId,
  status,
}: {
  ticketId: string;
  status: AdminTicketStatusValue;
}) {
  const [pending, startTransition] = React.useTransition();
  const router = useRouter();

  function run(
    action: (data: FormData) => Promise<AdminTicketActionState>,
    thenGoToList = false,
  ) {
    const data = new FormData();
    data.set("id", ticketId);
    data.set("ids", ticketId);
    startTransition(async () => {
      const result = await action(data);
      report(result);
      if (thenGoToList && result?.ok) router.push("/admin/tickets");
    });
  }

  return (
    <div className="flex flex-wrap items-center gap-1.5">
      {status === "CLOSED" ? (
        <Button
          type="button"
          size="sm"
          variant="outline"
          disabled={pending}
          onClick={() => run(adminReopenTicketAction)}
        >
          <RotateCcw className="size-3.5" />
          {tx.detail.reopen}
        </Button>
      ) : (
        <Button
          type="button"
          size="sm"
          variant="destructive"
          disabled={pending}
          onClick={() => run(adminCloseTicketAction)}
        >
          <XCircle className="size-3.5" />
          {tx.detail.close}
        </Button>
      )}

      <Button
        type="button"
        size="sm"
        variant="ghost"
        className="text-muted-foreground"
        disabled={pending}
        onClick={() => run(adminMarkTicketUnreadAction, true)}
      >
        <CheckCheck className="size-3.5" />
        {tx.detail.markUnread}
      </Button>
    </div>
  );
}
