import { useMemo } from "react";
import { Link, useParams } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import {
  ArrowLeft,
  BookOpen,
  Calendar,
  ClipboardList,
  Headphones,
  Library,
  MessageSquare,
  Mic,
  PenSquare,
  Sparkles,
  Type,
  Wand2,
  type LucideIcon,
} from "lucide-react";

import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { coursePlanService } from "@/services/coursePlan.service";
import { describeApiError } from "@/lib/api-client";
import type {
  CoursePlan,
  CoursePlanMaterial,
  CoursePlanSkill,
  CoursePlanWeek,
} from "@/types";

/**
 * Detail page for a single AI-generated course plan.
 *
 * Sections:
 *   - Header with course metadata + CEFR badge
 *   - Course description
 *   - Objectives list
 *   - Learning outcomes grouped by skill
 *   - Grammar scope
 *   - Assessment breakdown
 *   - Resources
 *   - Weekly delivery plan (accordion). Each week shows the items table
 *     from the AI plus a "Generate materials" button. When the user
 *     clicks it, we POST to `/weeks/:n/materials` and re-render the
 *     week content with the returned reading/listening/grammar/…
 *     materials.
 */

const SKILL_ICONS: Record<string, LucideIcon> = {
  reading: BookOpen,
  writing: PenSquare,
  listening: Headphones,
  speaking: Mic,
  grammar: Type,
  vocabulary: Library,
  integrated: MessageSquare,
};

export default function AdminCoursePlanDetail() {
  const { t } = useTranslation();
  const params = useParams<{ planId: string }>();
  const planId = Number(params.planId);
  const qc = useQueryClient();

  const { data, isLoading, isError, error } = useQuery({
    queryKey: ["course-plan", planId],
    queryFn: () => coursePlanService.get(planId),
    enabled: Number.isFinite(planId) && planId > 0,
  });

  const plan = data?.data as CoursePlan | undefined;

  const generateMut = useMutation({
    mutationFn: (weekNumber: number) =>
      coursePlanService.generateWeekMaterials(planId, weekNumber),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["course-plan", planId] });
      toast.success(t("coursePlan.weekMaterialsGenerated"));
    },
    onError: (err) =>
      toast.error(describeApiError(err, t("coursePlan.weekMaterialsFailed"))),
  });

  const materialsByWeek = useMemo(() => {
    const map = new Map<number, CoursePlanMaterial[]>();
    if (!plan?.materials) return map;
    for (const m of plan.materials) {
      const list = map.get(m.week_number) ?? [];
      list.push(m);
      map.set(m.week_number, list);
    }
    return map;
  }, [plan?.materials]);

  return (
    <div className="space-y-6">
      <Button variant="ghost" size="sm" asChild className="-ml-2 text-muted-foreground">
        <Link to="/admin/course-plans" className="flex items-center gap-1">
          <ArrowLeft className="h-4 w-4" />
          {t("coursePlan.backToList")}
        </Link>
      </Button>

      {isLoading && (
        <div className="space-y-4">
          <Skeleton className="h-20 rounded-lg" />
          <Skeleton className="h-40 rounded-lg" />
          <Skeleton className="h-60 rounded-lg" />
        </div>
      )}

      {isError && (
        <div className="rounded-md border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">
          {describeApiError(error, t("coursePlan.loadFailed"))}
        </div>
      )}

      {plan && (
        <>
          {/* Header */}
          <Card>
            <CardHeader>
              <div className="flex items-start justify-between gap-3 flex-wrap">
                <div className="space-y-1 flex-1 min-w-0">
                  <CardTitle className="text-2xl">{plan.name}</CardTitle>
                  {plan.description && (
                    <CardDescription className="max-w-3xl">
                      {plan.description}
                    </CardDescription>
                  )}
                </div>
                <div className="flex gap-2 flex-wrap">
                  <Badge variant="secondary" className="uppercase">
                    {plan.cefr_level || "—"}
                  </Badge>
                  <Badge variant="outline">
                    {t("coursePlan.weeksCount", { count: plan.total_weeks })}
                  </Badge>
                  <Badge variant="outline">
                    {t("coursePlan.hoursPerWeek", {
                      count: plan.contact_hours_per_week,
                    })}
                  </Badge>
                </div>
              </div>
              {plan.skills_division && (
                <p className="text-sm text-muted-foreground">
                  {plan.skills_division}
                </p>
              )}
            </CardHeader>
          </Card>

          {/* Objectives */}
          {plan.objectives.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base flex items-center gap-2">
                  <ClipboardList className="h-4 w-4 text-primary" />
                  {t("coursePlan.sections.objectives")}
                </CardTitle>
              </CardHeader>
              <CardContent>
                <ol className="list-decimal list-inside space-y-1 text-sm">
                  {plan.objectives.map((obj, i) => (
                    <li key={i}>{obj}</li>
                  ))}
                </ol>
              </CardContent>
            </Card>
          )}

          {/* Outcomes per skill */}
          {Object.keys(plan.outcomes).length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base flex items-center gap-2">
                  <Sparkles className="h-4 w-4 text-primary" />
                  {t("coursePlan.sections.outcomes")}
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                {(Object.keys(plan.outcomes) as CoursePlanSkill[]).map((skill) => {
                  const list = plan.outcomes[skill];
                  if (!list?.length) return null;
                  const Icon = SKILL_ICONS[skill] ?? ClipboardList;
                  return (
                    <div key={skill}>
                      <div className="flex items-center gap-2 mb-2">
                        <Icon className="h-4 w-4" />
                        <div className="font-medium capitalize">{t(`coursePlan.skill.${skill}`, skill)}</div>
                      </div>
                      <ul className="space-y-1 text-sm">
                        {list.map((o) => (
                          <li key={o.code} className="flex gap-2">
                            <Badge variant="outline" className="font-mono text-[10px] shrink-0">
                              {o.code}
                            </Badge>
                            <span className="flex-1">{o.description}</span>
                          </li>
                        ))}
                      </ul>
                    </div>
                  );
                })}
              </CardContent>
            </Card>
          )}

          {/* Grammar scope */}
          {plan.grammar.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base flex items-center gap-2">
                  <Type className="h-4 w-4 text-primary" />
                  {t("coursePlan.sections.grammar")}
                </CardTitle>
              </CardHeader>
              <CardContent>
                <ul className="space-y-2 text-sm">
                  {plan.grammar.map((g) => (
                    <li key={g.code}>
                      <div className="font-medium">
                        <Badge variant="outline" className="font-mono text-[10px] mr-2">
                          {g.code}
                        </Badge>
                        {g.label}
                      </div>
                      {g.sub_items?.length ? (
                        <ul className="list-disc list-inside ml-6 mt-1 text-muted-foreground text-xs">
                          {g.sub_items.map((s, i) => (
                            <li key={i}>{s}</li>
                          ))}
                        </ul>
                      ) : null}
                    </li>
                  ))}
                </ul>
              </CardContent>
            </Card>
          )}

          {/* Weekly delivery plan */}
          {plan.weeks && plan.weeks.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base flex items-center gap-2">
                  <Calendar className="h-4 w-4 text-primary" />
                  {t("coursePlan.sections.delivery")}
                </CardTitle>
                <CardDescription>
                  {t("coursePlan.deliveryHint")}
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Accordion type="multiple" className="w-full">
                  {plan.weeks.map((week) => (
                    <WeekAccordionItem
                      key={week.id}
                      week={week}
                      materials={materialsByWeek.get(week.week_number) ?? []}
                      generating={generateMut.isPending && generateMut.variables === week.week_number}
                      onGenerate={() => generateMut.mutate(week.week_number)}
                    />
                  ))}
                </Accordion>
              </CardContent>
            </Card>
          )}
        </>
      )}
    </div>
  );
}

function WeekAccordionItem({
  week,
  materials,
  generating,
  onGenerate,
}: {
  week: CoursePlanWeek;
  materials: CoursePlanMaterial[];
  generating: boolean;
  onGenerate: () => void;
}) {
  const { t } = useTranslation();
  return (
    <AccordionItem value={String(week.week_number)}>
      <AccordionTrigger className="text-left">
        <div className="flex-1 flex items-center gap-3 min-w-0">
          <Badge variant="outline" className="shrink-0">
            {t("coursePlan.weekN", { n: week.week_number })}
          </Badge>
          <div className="flex-1 min-w-0">
            <div className="font-medium truncate">{week.focus || week.unit || "—"}</div>
            {week.date_label && (
              <div className="text-xs text-muted-foreground truncate">
                {week.date_label}
              </div>
            )}
          </div>
          {materials.length > 0 && (
            <Badge variant="secondary" className="shrink-0">
              {t("coursePlan.materialsCount", { count: materials.length })}
            </Badge>
          )}
        </div>
      </AccordionTrigger>
      <AccordionContent className="space-y-4">
        {/* Items table */}
        {week.items.length > 0 && (
          <div className="rounded-md border overflow-hidden">
            <table className="w-full text-sm">
              <thead className="bg-muted/50 text-xs uppercase text-muted-foreground">
                <tr>
                  <th className="px-3 py-2 text-left font-medium">
                    {t("coursePlan.table.skill")}
                  </th>
                  <th className="px-3 py-2 text-left font-medium">
                    {t("coursePlan.table.outcomes")}
                  </th>
                  <th className="px-3 py-2 text-left font-medium">
                    {t("coursePlan.table.remarks")}
                  </th>
                </tr>
              </thead>
              <tbody>
                {week.items.map((item, i) => {
                  const Icon = SKILL_ICONS[item.skill] ?? ClipboardList;
                  return (
                    <tr key={i} className="border-t">
                      <td className="px-3 py-2">
                        <span className="flex items-center gap-1.5 capitalize">
                          <Icon className="h-3.5 w-3.5 text-muted-foreground" />
                          {item.skill}
                        </span>
                      </td>
                      <td className="px-3 py-2 flex flex-wrap gap-1">
                        {item.outcome_codes.map((c) => (
                          <Badge
                            key={c}
                            variant="outline"
                            className="font-mono text-[10px]"
                          >
                            {c}
                          </Badge>
                        ))}
                      </td>
                      <td className="px-3 py-2 text-muted-foreground">
                        {item.remarks || "—"}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        {/* Generate materials */}
        <div className="flex flex-wrap items-center gap-2">
          <Button size="sm" onClick={onGenerate} disabled={generating}>
            <Wand2 className="mr-1 h-4 w-4" />
            {generating
              ? t("coursePlan.generating")
              : materials.length > 0
                ? t("coursePlan.regenerateMaterials")
                : t("coursePlan.generateMaterials")}
          </Button>
          <span className="text-xs text-muted-foreground">
            {t("coursePlan.generateHint")}
          </span>
        </div>

        {/* Generated materials */}
        {materials.length > 0 && (
          <div className="space-y-3">
            {materials.map((m) => (
              <MaterialCard key={m.id} material={m} />
            ))}
          </div>
        )}
      </AccordionContent>
    </AccordionItem>
  );
}

function MaterialCard({ material }: { material: CoursePlanMaterial }) {
  const { t } = useTranslation();
  const Icon = SKILL_ICONS[material.skill] ?? ClipboardList;
  return (
    <Card>
      <CardHeader className="pb-2">
        <div className="flex items-center gap-2 flex-wrap">
          <Icon className="h-4 w-4 text-primary" />
          <CardTitle className="text-base flex-1 min-w-0">{material.title}</CardTitle>
          <Badge variant="outline" className="text-[10px]">
            {t(`coursePlan.materialType.${material.material_type}`, material.material_type)}
          </Badge>
        </div>
        {material.summary && (
          <CardDescription>{material.summary}</CardDescription>
        )}
      </CardHeader>
      <CardContent>
        <pre className="whitespace-pre-wrap text-xs font-mono bg-muted/40 rounded-md p-3 max-h-80 overflow-auto">
          {material.body_text || JSON.stringify(material.body, null, 2)}
        </pre>
      </CardContent>
    </Card>
  );
}
