import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { useMemo, useState } from "react";
import { toast } from "sonner";

import { AppShell } from "@/components/app-shell";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Skeleton } from "@/components/ui/skeleton";
import { LIKERT_LABELS } from "@/lib/assessment";
import { getAssessmentState, saveResponses, submitAssessment } from "@/lib/assessment.functions";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/_authenticated/assess")({
  head: () => ({
    meta: [
      { title: "Take the Growth Assessment | UZIA Academy" },
      {
        name: "description",
        content: "Answer the MSME growth assessment, one category at a time.",
      },
      { name: "robots", content: "noindex" },
    ],
  }),
  component: TakeAssessment,
});

function TakeAssessment() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const fetchState = useServerFn(getAssessmentState);
  const save = useServerFn(saveResponses);
  const submit = useServerFn(submitAssessment);

  const { data, isLoading } = useQuery({
    queryKey: ["assessment-state"],
    queryFn: () => fetchState(),
  });

  const [step, setStep] = useState(0);
  const [answers, setAnswers] = useState<Record<string, number> | null>(null);
  const current = answers ?? data?.answers ?? {};

  const categories = data?.categories ?? [];
  const questions = useMemo(
    () => (data?.questions ?? []).filter((q) => q.category_id === categories[step]?.id),
    [data, categories, step],
  );

  const saveMutation = useMutation({
    mutationFn: (rows: { question_id: string; score: number }[]) =>
      save({ data: { answers: rows } }),
  });

  const submitMutation = useMutation({
    mutationFn: () => submit(),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ["my-results"] });
      toast.success("Assessment complete — here are your results.");
      navigate({ to: "/results" });
    },
    onError: (e) => toast.error(e instanceof Error ? e.message : "Could not submit"),
  });

  if (isLoading || !data) {
    return (
      <AppShell title="Growth assessment">
        <Skeleton className="h-72 w-full" />
      </AppShell>
    );
  }

  const category = categories[step];
  const allAnswered = questions.every((q) => Boolean(current[q.id]));
  const isLast = step === categories.length - 1;
  const answeredCount = (data.questions ?? []).filter((q) => Boolean(current[q.id])).length;

  function setAnswer(questionId: string, score: number) {
    const next = { ...current, [questionId]: score };
    setAnswers(next);
    saveMutation.mutate([{ question_id: questionId, score }]);
  }

  async function onNext() {
    if (isLast) {
      const remaining = (data?.questions ?? []).filter((q) => !current[q.id]);
      if (remaining.length > 0) {
        toast.error(`${remaining.length} question(s) still unanswered.`);
        return;
      }
      submitMutation.mutate();
      return;
    }
    setStep(step + 1);
    window.scrollTo({ top: 0 });
  }

  return (
    <AppShell
      title="Growth assessment"
      description="Answer honestly — the score is only useful if it reflects reality."
    >
      <div className="mx-auto max-w-3xl">
        <div className="flex items-center justify-between text-sm text-muted-foreground">
          <span>
            Section {step + 1} of {categories.length}
          </span>
          <span>
            {answeredCount} / {data.questions.length} answered
          </span>
        </div>
        <Progress value={(answeredCount / Math.max(data.questions.length, 1)) * 100} className="mt-3" />

        <div className="mt-8 rounded-2xl border border-border bg-card p-6 sm:p-8">
          <h2 className="font-display text-xl font-bold">{category?.name}</h2>
          <p className="mt-2 text-sm text-muted-foreground">{category?.description}</p>

          <div className="mt-8 space-y-8">
            {questions.map((q, i) => (
              <div key={q.id}>
                <p className="text-sm font-medium">
                  {i + 1}. {q.prompt}
                </p>
                <div className="mt-3 grid gap-2 sm:grid-cols-5">
                  {LIKERT_LABELS.map((label, idx) => {
                    const value = idx + 1;
                    const selected = current[q.id] === value;
                    return (
                      <button
                        key={label}
                        type="button"
                        onClick={() => setAnswer(q.id, value)}
                        className={cn(
                          "rounded-lg border px-3 py-2.5 text-left text-xs transition-colors sm:text-center",
                          selected
                            ? "border-primary bg-primary text-primary-foreground"
                            : "border-border bg-surface text-muted-foreground hover:border-primary/50",
                        )}
                      >
                        <span className="block font-semibold">{value}</span>
                        {label}
                      </button>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="mt-6 flex items-center justify-between gap-3">
          <Button
            variant="outline"
            disabled={step === 0}
            onClick={() => {
              setStep(step - 1);
              window.scrollTo({ top: 0 });
            }}
          >
            Back
          </Button>
          <Button
            onClick={onNext}
            disabled={!allAnswered || submitMutation.isPending}
            className={isLast ? "bg-gold text-gold-foreground hover:bg-gold/90" : undefined}
          >
            {isLast
              ? submitMutation.isPending
                ? "Scoring…"
                : "Submit and see results"
              : "Next section"}
          </Button>
        </div>
        <p className="mt-3 text-center text-xs text-muted-foreground">
          Your answers save automatically — you can leave and come back.
        </p>
      </div>
    </AppShell>
  );
}
