import { useCallback, useEffect, useMemo, useState } from "react";
import { Link, createFileRoute } from "@tanstack/react-router";
import { ArrowLeft, CheckCircle2, Loader2, Send, ShieldAlert, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { EmptyState, SectionCard } from "@/components/ledger/Primitives";
import { QueryPriorityBadge, QueryThread, queryStatusTone } from "@/components/ledger/QueryThread";
import { Pill } from "@/components/ledger/StatusBadge";
import { useAuthSession } from "@/hooks/useAuthSession";
import { fetchQueryApi } from "@/lib/api";
import { eur, useLedger } from "@/lib/ledger-store";
import type { ClientQuery } from "@/lib/ledger-types";

function QueryRouteError({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <SectionCard>
      <EmptyState
        icon={X}
        title="Unable to load this query."
        description={error.message || "Something went wrong while opening this question."}
        action={
          <div className="flex flex-wrap justify-center gap-2">
            <Button variant="outline" onClick={reset}>
              Try again
            </Button>
            <Button variant="ghost" asChild>
              <Link to="/queries">Back to Client queries</Link>
            </Button>
          </div>
        }
      />
    </SectionCard>
  );
}

export const Route = createFileRoute("/queries/$id")({
  component: QueryDetailPage,
  errorComponent: QueryRouteError,
  pendingComponent: QueryLoading,
});

function QueryLoading() {
  return (
    <div className="flex items-center gap-3 px-1 py-8 text-[13px] text-muted-foreground">
      <Loader2 size={16} className="animate-spin text-brand" aria-hidden="true" />
      Loading query...
    </div>
  );
}

function QueryDetailPage() {
  const { id } = Route.useParams();
  const session = useAuthSession("firm");
  const { clientName, getInvoice, replyToQuery, resolveQuery, cancelQuery } = useLedger();

  const [query, setQuery] = useState<ClientQuery | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [statusCode, setStatusCode] = useState<number | null>(null);
  const [reply, setReply] = useState("");
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    if (!session?.email) return;
    setLoading(true);
    setError(null);
    setStatusCode(null);
    try {
      const next = await fetchQueryApi(id, { platform: "firm", email: session.email });
      setQuery(next);
    } catch (err) {
      setQuery(null);
      const message = err instanceof Error ? err.message : "Unable to load this query.";
      setError(message);
      const code = (err as Error & { status?: number }).status;
      setStatusCode(typeof code === "number" ? code : null);
    } finally {
      setLoading(false);
    }
  }, [id, session?.email]);

  useEffect(() => {
    void load();
  }, [load]);

  const invoice = useMemo(
    () => (query?.invoiceId ? getInvoice(query.invoiceId) : undefined),
    [getInvoice, query?.invoiceId],
  );

  if (loading) {
    return <QueryLoading />;
  }

  if (error || !query) {
    const unauthorized = statusCode === 403;
    const notFound = statusCode === 404;
    return (
      <SectionCard>
        <EmptyState
          icon={unauthorized ? ShieldAlert : X}
          title={
            unauthorized
              ? "Access denied"
              : notFound
                ? "Query not found"
                : "Unable to load this query."
          }
          description={
            unauthorized
              ? "You do not have access to this query."
              : notFound
                ? "This query may have been deleted or you may not have access to it."
                : error ?? "This query may have been deleted or you may not have access to it."
          }
          action={
            <div className="flex flex-wrap justify-center gap-2">
              {!unauthorized ? (
                <Button variant="outline" onClick={() => void load()}>
                  Try again
                </Button>
              ) : null}
              <Button variant="ghost" asChild>
                <Link to="/queries">← Back to Client queries</Link>
              </Button>
            </div>
          }
        />
      </SectionCard>
    );
  }

  const status = query.status ?? "";
  const isClosed = status === "Resolved" || status === "Cancelled";
  const canReply = status === "Requested" || status === "Delivered" || status === "Answered";
  const canResolve = status === "Answered";
  const canCancel = status === "Requested" || status === "Delivered" || status === "Answered";
  const question = query.question || query.messages?.[0]?.message || "Client query";

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center gap-3">
        <Button variant="ghost" size="sm" asChild>
          <Link to="/queries">
            <ArrowLeft size={15} /> Back to Client queries
          </Link>
        </Button>
        <div className="min-w-0 flex-1">
          <h1 className="text-[20px] font-semibold tracking-tight">{question}</h1>
          <p className="text-[13px] text-muted-foreground">
            {query.id} · {clientName(query.clientId)} · Created {query.createdAt}
            {query.createdBy ? ` · ${query.createdBy}` : ""}
          </p>
        </div>
        <QueryPriorityBadge priority={query.priority ?? "Normal"} />
        <Pill tone={queryStatusTone(status)}>{status || "Unknown"}</Pill>
      </div>

      {query.invoiceId ? (
        <SectionCard title="Related document" bodyClassName="p-5">
          <p className="text-[14px] font-semibold">
            {invoice?.supplier || invoice?.file || query.invoiceId}
          </p>
          <p className="mt-1 text-[13px] text-muted-foreground">
            {invoice?.number ? `Invoice ${invoice.number}` : invoice?.file || query.invoiceId}
            {invoice?.total ? ` · ${eur(invoice.total)}` : ""}
          </p>
          <Button size="sm" variant="outline" className="mt-3" asChild>
            <Link to="/invoices/$id" params={{ id: query.invoiceId }}>
              Open document review
            </Link>
          </Button>
        </SectionCard>
      ) : null}

      <SectionCard title="Conversation" bodyClassName="p-5 space-y-4">
        <QueryThread messages={query.messages ?? []} />

        {isClosed ? (
          <p className="text-[13px] text-muted-foreground">
            {status === "Cancelled" ? "This question was cancelled" : "This question is resolved"}
            {query.resolvedBy ? ` · ${query.resolvedBy}` : ""}
            {query.resolvedAt ? ` · ${query.resolvedAt}` : ""}.
          </p>
        ) : (
          <div className="space-y-3 border-t border-border pt-4">
            {canReply ? (
              <>
                <Label htmlFor="firm-reply">Write a reply</Label>
                <Textarea
                  id="firm-reply"
                  value={reply}
                  onChange={(e) => setReply(e.target.value)}
                  placeholder="Thanks, I've confirmed this."
                  className="min-h-20"
                />
              </>
            ) : null}
            <div className="flex flex-wrap gap-2">
              {canReply ? (
                <Button
                  disabled={!reply.trim() || busy}
                  onClick={() => {
                    const text = reply.trim();
                    if (!text) return;
                    setBusy(true);
                    void replyToQuery(query.id, text)
                      .then(() => {
                        setReply("");
                        return load();
                      })
                      .catch(() => undefined)
                      .finally(() => setBusy(false));
                  }}
                >
                  <Send size={15} /> Send reply
                </Button>
              ) : null}
              {canResolve ? (
                <Button
                  variant="brand"
                  disabled={busy}
                  onClick={() => {
                    setBusy(true);
                    void resolveQuery(query.id)
                      .then(() => load())
                      .catch(() => undefined)
                      .finally(() => setBusy(false));
                  }}
                >
                  <CheckCircle2 size={15} /> Resolve
                </Button>
              ) : null}
              {canCancel ? (
                <Button
                  variant="outline"
                  disabled={busy}
                  onClick={() => {
                    setBusy(true);
                    void cancelQuery(query.id)
                      .then(() => load())
                      .catch(() => undefined)
                      .finally(() => setBusy(false));
                  }}
                >
                  <X size={15} /> Cancel
                </Button>
              ) : null}
            </div>
          </div>
        )}
      </SectionCard>
    </div>
  );
}
