import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { motion } from "motion/react";
import { toast } from "sonner";
import { trpc } from "@/lib/trpc";
import { useLiveUpdates, type LiveUpdateRule } from "@/hooks";
import { Skeleton } from "@/components/ui/skeleton";
import { Button } from "@/components/ui/button";
import { InboxList } from "@/components/InboxList";
import { InboxDetailPanel } from "@/components/InboxDetailPanel";
import { HQNeedsReviewSection } from "@/components/hq/HQNeedsReviewSection";
import { HQNeedsApprovalSection } from "@/components/hq/HQNeedsApprovalSection";
import { HQResolvingConflictsSection } from "@/components/hq/HQResolvingConflictsSection";
import { HQBlockedSection } from "@/components/hq/HQBlockedSection";
import { HQEmptyState } from "@/components/hq/HQEmptyState";

export const Route = createFileRoute("/hq")({
  component: HeadquartersPage,
});

const HQ_LIVE_UPDATE_RULES: LiveUpdateRule[] = [
  { prefix: "initiative:", invalidate: ["getHeadquartersDashboard"] },
  { prefix: "phase:", invalidate: ["getHeadquartersDashboard"] },
  { prefix: "agent:", invalidate: ["getHeadquartersDashboard"] },
  { prefix: "agent:", invalidate: ["listWaitingAgents", "listMessages"] },
];

export function HeadquartersPage() {
  useLiveUpdates(HQ_LIVE_UPDATE_RULES);
  const query = trpc.getHeadquartersDashboard.useQuery();

  const [selectedAgentId, setSelectedAgentId] = useState<string | null>(null);

  const utils = trpc.useUtils();
  const agentsQuery = trpc.listWaitingAgents.useQuery();
  const messagesQuery = trpc.listMessages.useQuery({});
  const questionsQuery = trpc.getAgentQuestions.useQuery(
    { id: selectedAgentId! },
    { enabled: !!selectedAgentId }
  );

  const resumeAgentMutation = trpc.resumeAgent.useMutation({
    onSuccess: () => {
      setSelectedAgentId(null);
      toast.success("Answer submitted");
    },
    onError: () => {
      toast.error("Failed to submit answer");
    },
  });

  const dismissQuestionsMutation = trpc.stopAgent.useMutation({
    onSuccess: () => {
      setSelectedAgentId(null);
      toast.success("Questions dismissed");
    },
    onError: () => {
      toast.error("Failed to dismiss questions");
    },
  });

  const respondToMessageMutation = trpc.respondToMessage.useMutation({
    onSuccess: () => {
      setSelectedAgentId(null);
      toast.success("Response sent");
    },
    onError: () => {
      toast.error("Failed to send response");
    },
  });

  const agents = agentsQuery.data ?? [];
  const messages = messagesQuery.data ?? [];
  const selectedAgent = selectedAgentId
    ? agents.find((a) => a.id === selectedAgentId) ?? null
    : null;
  const selectedMessage = selectedAgentId
    ? messages
        .filter((m) => m.senderId === selectedAgentId)
        .sort(
          (a, b) =>
            new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
        )[0] ?? null
    : null;
  const pendingQuestions = questionsQuery.data ?? null;

  function handleRefresh() {
    void utils.listWaitingAgents.invalidate();
    void utils.listMessages.invalidate();
  }

  function handleSubmitAnswers(answers: Record<string, string>) {
    if (!selectedAgentId) return;
    resumeAgentMutation.mutate({ id: selectedAgentId, answers });
  }

  function handleDismissQuestions() {
    if (!selectedAgentId) return;
    dismissQuestionsMutation.mutate({ id: selectedAgentId });
  }

  function handleDismiss() {
    if (!selectedMessage) return;
    respondToMessageMutation.mutate({
      id: selectedMessage.id,
      response: "Acknowledged",
    });
  }

  const serializedAgents = agents.map((a) => ({
    id: a.id,
    name: a.name,
    status: a.status,
    taskId: a.taskId ?? "",
    updatedAt: String(a.updatedAt),
  }));

  const serializedMessages = messages.map((m) => ({
    id: m.id,
    senderId: m.senderId,
    content: m.content,
    requiresResponse: m.requiresResponse,
    status: m.status,
    createdAt: String(m.createdAt),
  }));

  if (query.isLoading) {
    return (
      <motion.div
        className="mx-auto max-w-4xl space-y-6"
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.3 }}
      >
        <div>
          <h1 className="text-xl font-semibold">Headquarters</h1>
          <p className="text-sm text-muted-foreground">
            Items waiting for your attention.
          </p>
        </div>
        <div className="space-y-4">
          {[1, 2, 3].map((i) => (
            <Skeleton key={i} className="h-16 w-full rounded-lg" />
          ))}
        </div>
      </motion.div>
    );
  }

  if (query.isError) {
    return (
      <motion.div
        className="mx-auto max-w-4xl space-y-6"
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.3 }}
      >
        <div className="flex flex-col items-center justify-center py-24 gap-3 text-center">
          <p className="text-sm text-muted-foreground">
            Failed to load headquarters data.
          </p>
          <Button variant="outline" size="sm" onClick={() => query.refetch()}>
            Retry
          </Button>
        </div>
      </motion.div>
    );
  }

  const data = query.data!;

  const hasAny =
    data.waitingForInput.length > 0 ||
    data.pendingReviewInitiatives.length > 0 ||
    data.pendingReviewPhases.length > 0 ||
    data.planningInitiatives.length > 0 ||
    data.resolvingConflicts.length > 0 ||
    data.blockedPhases.length > 0;

  return (
    <motion.div
      className="mx-auto max-w-4xl space-y-6"
      initial={{ opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3 }}
    >
      <div>
        <h1 className="text-xl font-semibold">Headquarters</h1>
        <p className="text-sm text-muted-foreground">
          Items waiting for your attention.
        </p>
      </div>

      {!hasAny ? (
        <HQEmptyState />
      ) : (
        <div className="space-y-8">
          {data.waitingForInput.length > 0 && (
            <div className="space-y-3">
              <h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide">
                Waiting for Input
              </h2>
              <div className="grid grid-cols-1 gap-6 lg:grid-cols-[1fr_400px]">
                {/* Left: agent list — hidden on mobile when an agent is selected */}
                <div className={selectedAgent ? "hidden lg:block" : undefined}>
                  <InboxList
                    agents={serializedAgents}
                    messages={serializedMessages}
                    selectedAgentId={selectedAgentId}
                    onSelectAgent={setSelectedAgentId}
                    onRefresh={handleRefresh}
                  />
                </div>
                {/* Right: detail panel */}
                {selectedAgent ? (
                  <InboxDetailPanel
                    agent={{
                      id: selectedAgent.id,
                      name: selectedAgent.name,
                      status: selectedAgent.status,
                      taskId: selectedAgent.taskId ?? null,
                      updatedAt: String(selectedAgent.updatedAt),
                    }}
                    message={
                      selectedMessage
                        ? {
                            id: selectedMessage.id,
                            content: selectedMessage.content,
                            requiresResponse: selectedMessage.requiresResponse,
                          }
                        : null
                    }
                    questions={
                      pendingQuestions
                        ? pendingQuestions.questions.map((q) => ({
                            id: q.id,
                            question: q.question,
                            options: q.options,
                            multiSelect: q.multiSelect,
                          }))
                        : null
                    }
                    isLoadingQuestions={questionsQuery.isLoading}
                    questionsError={
                      questionsQuery.isError ? questionsQuery.error.message : null
                    }
                    onBack={() => setSelectedAgentId(null)}
                    onSubmitAnswers={handleSubmitAnswers}
                    onDismissQuestions={handleDismissQuestions}
                    onDismissMessage={handleDismiss}
                    isSubmitting={resumeAgentMutation.isPending}
                    isDismissingQuestions={dismissQuestionsMutation.isPending}
                    isDismissingMessage={respondToMessageMutation.isPending}
                    submitError={
                      resumeAgentMutation.isError
                        ? resumeAgentMutation.error.message
                        : null
                    }
                    dismissMessageError={
                      respondToMessageMutation.isError
                        ? respondToMessageMutation.error.message
                        : null
                    }
                  />
                ) : (
                  <div className="hidden flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-border p-8 lg:flex">
                    <p className="text-sm font-medium text-muted-foreground">No agent selected</p>
                    <p className="text-xs text-muted-foreground/70">Select an agent from the list to answer their questions</p>
                  </div>
                )}
              </div>
            </div>
          )}
          {(data.pendingReviewInitiatives.length > 0 ||
            data.pendingReviewPhases.length > 0) && (
            <HQNeedsReviewSection
              initiatives={data.pendingReviewInitiatives}
              phases={data.pendingReviewPhases}
            />
          )}
          {data.planningInitiatives.length > 0 && (
            <HQNeedsApprovalSection items={data.planningInitiatives} />
          )}
          {data.resolvingConflicts.length > 0 && (
            <HQResolvingConflictsSection items={data.resolvingConflicts} />
          )}
          {data.blockedPhases.length > 0 && (
            <HQBlockedSection items={data.blockedPhases} />
          )}
        </div>
      )}
    </motion.div>
  );
}
