import { useMemo, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import {
  ArrowLeft,
  BookOpen,
  Calendar,
  ClipboardList,
  Headphones,
  Image as ImageIcon,
  Library,
  MessageSquare,
  Mic,
  Music,
  PenSquare,
  Sparkles,
  Type,
  Video,
  type LucideIcon,
} from "lucide-react";

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

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

/**
 * Student detail view for an assigned AI course plan.
 *
 * Server-side authorisation: the `/api/student/course-plans/:id` endpoint
 * returns 403 unless the current user is in the plan's assignment list,
 * so we can render unconditionally as soon as the query resolves.
 *
 * The page is intentionally read-only — students can play audio, view
 * images, and watch video, but they can't (re)generate content.
 */
export default function StudentCoursePlanDetail() {
  const { t } = useTranslation();
  const { planId: planIdRaw } = useParams<{ planId: string }>();
  const planId = Number(planIdRaw);

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

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

  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="/student/course-plans" className="flex items-center gap-1">
          <ArrowLeft className="h-4 w-4" />
          {t("coursePlan.student.backToList")}
        </Link>
      </Button>

      {isLoading && (
        <div className="space-y-3">
          <Skeleton className="h-20" />
          <Skeleton className="h-40" />
          <Skeleton className="h-40" />
        </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 && (
        <>
          <Card>
            <CardHeader>
              <div className="flex items-start justify-between gap-3 flex-wrap">
                <div className="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.assignment && (
                <p className="text-xs text-muted-foreground flex items-center gap-1.5">
                  <Calendar className="h-3.5 w-3.5" />
                  {plan.assignment.due_date
                    ? t("coursePlan.student.due", { date: plan.assignment.due_date })
                    : t("coursePlan.student.noDue")}
                  {plan.assignment.assigned_by_name && (
                    <span>
                      ·{" "}
                      {t("coursePlan.student.assignedBy", {
                        name: plan.assignment.assigned_by_name,
                      })}
                    </span>
                  )}
                </p>
              )}
              {plan.assignment?.message && (
                <p className="text-sm bg-muted/40 rounded-md px-3 py-2 mt-2">
                  {plan.assignment.message}
                </p>
              )}
            </CardHeader>
          </Card>

          {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((o, i) => (
                    <li key={i}>{o}</li>
                  ))}
                </ol>
              </CardContent>
            </Card>
          )}

          {plan.weeks && plan.weeks.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="text-base flex items-center gap-2">
                  <Sparkles 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((w) => (
                    <StudentWeek
                      key={w.id}
                      week={w}
                      materials={materialsByWeek.get(w.week_number) ?? []}
                    />
                  ))}
                </Accordion>
              </CardContent>
            </Card>
          )}
        </>
      )}
    </div>
  );
}

function StudentWeek({
  week,
  materials,
}: {
  week: CoursePlanWeek;
  materials: CoursePlanMaterial[];
}) {
  const { t } = useTranslation();
  const [skillFilter, setSkillFilter] = useState<string>("all");
  const skills = useMemo(
    () => Array.from(new Set(materials.map((m) => m.skill))).sort(),
    [materials],
  );
  const filteredMaterials = useMemo(
    () => materials.filter((m) => skillFilter === "all" || m.skill === skillFilter),
    [materials, skillFilter],
  );
  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>
        </div>
      </AccordionTrigger>
      <AccordionContent className="space-y-3">
        {skills.length > 0 && (
          <div className="flex items-center gap-1 flex-wrap">
            <Button
              size="sm"
              variant={skillFilter === "all" ? "default" : "outline"}
              onClick={() => setSkillFilter("all")}
            >
              {t("common.all", "All")}
            </Button>
            {skills.map((s) => (
              <Button
                key={s}
                size="sm"
                variant={skillFilter === s ? "default" : "outline"}
                onClick={() => setSkillFilter(s)}
                className="capitalize"
              >
                {s}
              </Button>
            ))}
          </div>
        )}
        {materials.length === 0 && (
          <p className="text-sm italic text-muted-foreground">
            {t("coursePlan.media.noMedia")}
          </p>
        )}
        {filteredMaterials.map((m) => (
          <StudentMaterial key={m.id} material={m} />
        ))}
      </AccordionContent>
    </AccordionItem>
  );
}

function StudentMaterial({ 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>
          <SkillBadge skill={material.skill} />
        </div>
        {material.summary && <CardDescription>{material.summary}</CardDescription>}
        {material.share_date && (
          <CardDescription>
            {t("coursePlan.shareDate", "Share date")}: {material.share_date}
          </CardDescription>
        )}
      </CardHeader>
      <CardContent className="space-y-3">
        {(material.media ?? []).map((m) => (
          <StudentMediaTile key={m.id} media={m} />
        ))}
        <MaterialBookView material={material} />
      </CardContent>
    </Card>
  );
}

function StudentMediaTile({ media }: { media: CoursePlanMedia }) {
  const url = withAuthQuery(media.preview_url || media.download_url || "");
  if (!url) return null;
  return (
    <div className="rounded-md border bg-muted/20 p-2 space-y-2">
      <div className="flex items-center gap-2">
        {media.kind === "audio" && <Music className="h-4 w-4" />}
        {media.kind === "image" && <ImageIcon className="h-4 w-4" />}
        {media.kind === "video" && <Video className="h-4 w-4" />}
        <span className="capitalize text-xs text-muted-foreground">
          {media.kind}
        </span>
      </div>
      {media.kind === "audio" && <audio src={url} controls className="w-full" />}
      {media.kind === "image" && (
        <img
          src={url}
          alt={media.title}
          className="w-full rounded-md max-h-72 object-contain bg-muted/30"
        />
      )}
      {media.kind === "video" && (
        <video src={url} controls className="w-full rounded-md max-h-72" />
      )}
    </div>
  );
}
