import { useNavigate } from "react-router-dom";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Plus, Trash2 } from "lucide-react";

import { StepWizard, type WizardStepDef } from "@/components/wizard/StepWizard";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { examsService } from "@/services/exams.service";
import { describeApiError } from "@/lib/api-client";
import type { ExamModule } from "@/types";

/**
 * Rubric creation wizard (4 steps).
 *
 * 1. Basics — name, skill (module), description
 * 2. Criteria — rows of name + max score
 * 3. Descriptors — per-criterion optional descriptors
 * 4. Review — summary then Finish calls examsService.createRubric
 *
 * Only Writing / Speaking make sense as rubric targets because the other
 * two modules (Listening / Reading) are auto-graded; QA flagged this as an
 * explicit UX requirement earlier in the project.
 */

interface CriterionDraft {
  name: string;
  max_score: number;
  description: string;
}

interface RubricWizardState {
  name: string;
  module: ExamModule;
  description: string;
  criteria: CriterionDraft[];
}

const INITIAL: RubricWizardState = {
  name: "",
  module: "writing",
  description: "",
  criteria: [
    { name: "Task Response", max_score: 9, description: "" },
    { name: "Coherence & Cohesion", max_score: 9, description: "" },
  ],
};

export default function RubricWizard() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const qc = useQueryClient();

  const createMut = useMutation({
    mutationFn: (data: Record<string, unknown>) =>
      examsService.createRubric(data as never),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["rubrics"] });
      toast.success(t("wizard.rubric.toastSuccess"));
      navigate("/admin/rubrics");
    },
    onError: (err: unknown) => {
      toast.error(describeApiError(err, t("wizard.rubric.toastError")));
    },
  });

  const steps: WizardStepDef<RubricWizardState>[] = [
    {
      id: "basics",
      titleKey: "wizard.rubric.step1.title",
      descriptionKey: "wizard.rubric.step1.description",
      validate: (s) => {
        if (!s.name.trim()) return t("wizard.rubric.errors.nameRequired");
        if (s.module !== "writing" && s.module !== "speaking") {
          return t("wizard.rubric.errors.moduleRestricted");
        }
        return null;
      },
      render: ({ state, update }) => (
        <div className="space-y-4">
          <div className="space-y-1.5">
            <Label htmlFor="rubric-name">{t("wizard.rubric.labels.name")}</Label>
            <Input
              id="rubric-name"
              value={state.name}
              onChange={(e) => update({ name: e.target.value })}
              placeholder={t("wizard.rubric.placeholders.name")}
            />
          </div>
          <div className="space-y-1.5">
            <Label>{t("wizard.rubric.labels.module")}</Label>
            <Select value={state.module} onValueChange={(v) => update({ module: v as ExamModule })}>
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="writing">{t("wizard.rubric.modules.writing")}</SelectItem>
                <SelectItem value="speaking">{t("wizard.rubric.modules.speaking")}</SelectItem>
              </SelectContent>
            </Select>
            <p className="text-xs text-muted-foreground">
              {t("wizard.rubric.moduleHint")}
            </p>
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="rubric-desc">{t("wizard.rubric.labels.description")}</Label>
            <Textarea
              id="rubric-desc"
              value={state.description}
              onChange={(e) => update({ description: e.target.value })}
              placeholder={t("wizard.rubric.placeholders.description")}
              rows={3}
            />
          </div>
        </div>
      ),
    },

    {
      id: "criteria",
      titleKey: "wizard.rubric.step2.title",
      descriptionKey: "wizard.rubric.step2.description",
      validate: (s) => {
        if (s.criteria.length === 0) return t("wizard.rubric.errors.criterionRequired");
        for (const c of s.criteria) {
          if (!c.name.trim()) return t("wizard.rubric.errors.criterionName");
          if (c.max_score < 1 || c.max_score > 100) {
            return t("wizard.rubric.errors.criterionScore");
          }
        }
        return null;
      },
      render: ({ state, update }) => (
        <div className="space-y-3">
          <div className="space-y-2">
            {state.criteria.map((c, i) => (
              <div key={i} className="flex items-end gap-2 rounded-md border p-3">
                <div className="flex-1 space-y-1.5">
                  <Label htmlFor={`crit-name-${i}`}>{t("wizard.rubric.labels.criterionName")}</Label>
                  <Input
                    id={`crit-name-${i}`}
                    value={c.name}
                    onChange={(e) => {
                      const next = [...state.criteria];
                      next[i] = { ...c, name: e.target.value };
                      update({ criteria: next });
                    }}
                    placeholder={t("wizard.rubric.placeholders.criterionName")}
                  />
                </div>
                <div className="w-24 space-y-1.5">
                  <Label htmlFor={`crit-score-${i}`}>{t("wizard.rubric.labels.maxScore")}</Label>
                  <Input
                    id={`crit-score-${i}`}
                    type="number"
                    min={1}
                    max={100}
                    value={c.max_score}
                    onChange={(e) => {
                      const next = [...state.criteria];
                      next[i] = { ...c, max_score: Number(e.target.value) || 0 };
                      update({ criteria: next });
                    }}
                  />
                </div>
                <Button
                  variant="ghost"
                  size="icon"
                  aria-label={t("wizard.rubric.removeCriterion")}
                  onClick={() => {
                    const next = state.criteria.filter((_, idx) => idx !== i);
                    update({ criteria: next });
                  }}
                  disabled={state.criteria.length === 1}
                  className="text-destructive"
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={() =>
              update({
                criteria: [
                  ...state.criteria,
                  { name: "", max_score: 9, description: "" },
                ],
              })
            }
          >
            <Plus className="mr-1 h-4 w-4" />
            {t("wizard.rubric.addCriterion")}
          </Button>
        </div>
      ),
    },

    {
      id: "descriptors",
      titleKey: "wizard.rubric.step3.title",
      descriptionKey: "wizard.rubric.step3.description",
      // Descriptors are optional — no validation.
      render: ({ state, update }) => (
        <div className="space-y-3">
          {state.criteria.map((c, i) => (
            <div key={i} className="space-y-1.5">
              <Label htmlFor={`crit-desc-${i}`}>
                {c.name || t("wizard.rubric.unnamedCriterion")}
              </Label>
              <Textarea
                id={`crit-desc-${i}`}
                value={c.description}
                onChange={(e) => {
                  const next = [...state.criteria];
                  next[i] = { ...c, description: e.target.value };
                  update({ criteria: next });
                }}
                placeholder={t("wizard.rubric.placeholders.descriptor")}
                rows={2}
              />
            </div>
          ))}
          <p className="text-xs text-muted-foreground">
            {t("wizard.rubric.descriptorHint")}
          </p>
        </div>
      ),
    },

    {
      id: "review",
      titleKey: "wizard.rubric.step4.title",
      descriptionKey: "wizard.rubric.step4.description",
      render: ({ state }) => (
        <div className="space-y-4 text-sm">
          <ReviewRow label={t("wizard.rubric.labels.name")} value={state.name} />
          <ReviewRow
            label={t("wizard.rubric.labels.module")}
            value={t(`wizard.rubric.modules.${state.module}`)}
          />
          {state.description && (
            <ReviewRow
              label={t("wizard.rubric.labels.description")}
              value={state.description}
              wrap
            />
          )}
          <div>
            <div className="font-medium mb-1">
              {t("wizard.rubric.step2.title")} ({state.criteria.length})
            </div>
            <ul className="rounded-md border divide-y">
              {state.criteria.map((c, i) => (
                <li key={i} className="flex items-start justify-between gap-3 p-2">
                  <div className="flex-1 min-w-0">
                    <div className="font-medium">{c.name}</div>
                    {c.description && (
                      <div className="text-muted-foreground text-xs mt-0.5">
                        {c.description}
                      </div>
                    )}
                  </div>
                  <div className="shrink-0 tabular-nums text-muted-foreground">
                    {t("wizard.rubric.maxLabel")}: {c.max_score}
                  </div>
                </li>
              ))}
            </ul>
          </div>
        </div>
      ),
    },
  ];

  return (
    <StepWizard<RubricWizardState>
      titleKey="wizard.rubric.title"
      subtitleKey="wizard.rubric.subtitle"
      backTo="/admin/smart-wizard"
      steps={steps}
      initialState={INITIAL}
      submitting={createMut.isPending}
      finishLabelKey="wizard.rubric.finish"
      onFinish={async (state) => {
        await createMut.mutateAsync({
          name: state.name.trim(),
          module: state.module,
          description: state.description.trim(),
          criteria: state.criteria.map((c) => ({
            name: c.name.trim(),
            description: c.description.trim(),
            max_score: c.max_score,
          })),
        });
      }}
    />
  );
}

function ReviewRow({ label, value, wrap }: { label: string; value: string; wrap?: boolean }) {
  return (
    <div className="grid grid-cols-[120px_1fr] gap-2">
      <div className="text-muted-foreground">{label}</div>
      <div className={wrap ? "whitespace-pre-wrap" : ""}>{value || "—"}</div>
    </div>
  );
}
