"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { ReportCardWarningsPanel } from "@/components/academic/ReportCardWarningsPanel";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input } from "@/components/ui/Field";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { SubjectAvatar } from "@/components/ui/SubjectAvatar";
import {
  ApiError,
  BranchItem,
  GradeLevel,
  apiGet,
  apiPatch,
  apiPut,
} from "@/lib/api";
import {
  CHART_OPTIONS,
  ChartKey,
  ReportCardItem,
  ReportCardSubjectRow,
} from "@/lib/report-cards";

interface SubjectItem {
  id: number;
  name: string;
  type?: string;
  coefficient?: number;
  grade_level_id?: number | null;
  is_active?: boolean;
  image_url?: string | null;
  field_coefficients?: Array<{
    study_field_id: number;
    study_field_name?: string | null;
    coefficient: number;
  }>;
}

export function ReportCardSettingsPanel({ cardId }: { cardId: number }) {
  const [card, setCard] = useState<ReportCardItem | null>(null);
  const [grades, setGrades] = useState<GradeLevel[]>([]);
  const [officialSubjects, setOfficialSubjects] = useState<SubjectItem[]>([]);
  const [extraSubjects, setExtraSubjects] = useState<SubjectItem[]>([]);
  const [branches, setBranches] = useState<BranchItem[]>([]);
  const [selectedGradeId, setSelectedGradeId] = useState<number | null>(null);
  const [subjectRows, setSubjectRows] = useState<ReportCardSubjectRow[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    setError(null);
    try {
      const [detail, branchList] = await Promise.all([
        apiGet<ReportCardItem>(`/report-cards/${cardId}`),
        apiGet<BranchItem[]>("/branches"),
      ]);
      const cardBranchIds = (detail.branches ?? []).map((b) => b.id).filter(Boolean);
      let gradeList: GradeLevel[] = [];
      if (cardBranchIds.length) {
        const lists = await Promise.all(
          cardBranchIds.map((branchId) =>
            apiGet<GradeLevel[]>(`/grade-levels?branch_id=${branchId}`),
          ),
        );
        const map = new Map<number, GradeLevel>();
        lists.flat().forEach((g) => map.set(g.id, g));
        gradeList = Array.from(map.values());
      } else {
        gradeList = await apiGet<GradeLevel[]>("/grade-levels");
      }
      setCard(detail);
      setGrades(gradeList);
      setBranches(branchList);
      setSubjectRows(detail.subjects ?? []);
      setSelectedGradeId((prev) => prev ?? gradeList[0]?.id ?? null);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
    }
  }, [cardId]);

  useEffect(() => {
    void load();
  }, [load]);

  useEffect(() => {
    if (!selectedGradeId || !card) return;
    const loadGradeSubjects = async () => {
      try {
        const official = await apiGet<SubjectItem[]>(
          `/subjects?grade_level_id=${selectedGradeId}&type=official&scope=org&active_only=1`,
        );
        setOfficialSubjects(official);
        if (card.kind === "unofficial") {
          const extra = await apiGet<SubjectItem[]>(
            `/subjects?type=extra&grade_level_id=${selectedGradeId}&active_only=1`,
          );
          setExtraSubjects(extra);
        } else {
          setExtraSubjects([]);
        }
      } catch {
        setOfficialSubjects([]);
        setExtraSubjects([]);
      }
    };
    void loadGradeSubjects();
  }, [selectedGradeId, card?.kind]);

  const catalogSubjects = useMemo(() => {
    if (card?.kind === "unofficial") {
      return [...officialSubjects, ...extraSubjects];
    }
    return officialSubjects;
  }, [card?.kind, officialSubjects, extraSubjects]);

  const selectedGrade = useMemo(
    () => grades.find((g) => g.id === selectedGradeId) ?? null,
    [grades, selectedGradeId],
  );

  const selectedCountForGrade = useMemo(() => {
    if (!selectedGradeId) return 0;
    return subjectRows.filter((r) => r.grade_level_id === selectedGradeId && r.included).length;
  }, [subjectRows, selectedGradeId]);

  const updateCardField = <K extends keyof ReportCardItem>(key: K, value: ReportCardItem[K]) => {
    setCard((prev) => (prev ? { ...prev, [key]: value } : prev));
  };

  const saveTemplate = async () => {
    if (!card) return;
    setSaving(true);
    setError(null);
    setSuccess(null);
    try {
      const updated = await apiPatch<ReportCardItem>(`/report-cards/${card.id}`, {
        name: card.name,
        footer_note: card.footer_note,
        header_text: card.header_text,
        footer_text: card.footer_text,
        min_score: Number(card.min_score),
        max_score: Number(card.max_score),
        rounding_mode: card.rounding_mode,
        is_visible: card.is_visible,
        show_average: card.show_average,
        show_gpa: card.show_gpa,
        show_descriptive: card.show_descriptive,
        show_discipline: card.show_discipline,
        show_discipline_descriptive: card.show_discipline_descriptive,
        enabled_charts: card.enabled_charts,
        is_active: card.is_active,
        branch_ids: card.kind === "official" ? undefined : card.branches.map((b) => b.id),
      });
      setCard(updated);
      setSuccess("تنظیمات کارنامه ذخیره شد.");
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ذخیره");
    } finally {
      setSaving(false);
    }
  };

  const rowFor = (subjectId: number): ReportCardSubjectRow => {
    const existing = subjectRows.find(
      (r) => r.subject_id === subjectId && r.grade_level_id === selectedGradeId,
    );
    return (
      existing ?? {
        grade_level_id: selectedGradeId!,
        subject_id: subjectId,
        included: false,
        warnings_enabled: false,
        warnings: [],
      }
    );
  };

  const upsertRow = (subjectId: number, patch: Partial<ReportCardSubjectRow>) => {
    if (!selectedGradeId) return;
    setSubjectRows((prev) => {
      const idx = prev.findIndex(
        (r) => r.subject_id === subjectId && r.grade_level_id === selectedGradeId,
      );
      if (idx === -1) {
        return [
          ...prev,
          {
            grade_level_id: selectedGradeId,
            subject_id: subjectId,
            included: false,
            warnings_enabled: false,
            warnings: [],
            ...patch,
          },
        ];
      }
      const next = [...prev];
      next[idx] = { ...next[idx], ...patch };
      return next;
    });
  };

  const saveSubjects = async () => {
    if (!card || !selectedGradeId) {
      setError("ابتدا پایه را انتخاب کنید.");
      return;
    }
    setSaving(true);
    setError(null);
    setSuccess(null);
    try {
      const currentGradePayload = catalogSubjects.map((subject) => {
        const row = rowFor(subject.id);
        return {
          grade_level_id: selectedGradeId,
          subject_id: subject.id,
          included: Boolean(row.included),
          warnings_enabled: Boolean(row.warnings_enabled),
          warnings: row.warnings_enabled ? row.warnings : [],
        };
      });

      const updated = await apiPut<ReportCardItem>(`/report-cards/${card.id}/subjects`, {
        subjects: currentGradePayload,
      });
      setCard(updated);
      setSubjectRows(updated.subjects ?? []);
      setSuccess(`دروس پایه «${selectedGrade?.name ?? ""}» ذخیره شد.`);
    } catch (err) {
      if (err instanceof ApiError) {
        const payload = err.payload as { message?: string; errors?: Record<string, string[]> };
        const firstFieldError = payload?.errors
          ? Object.values(payload.errors).flat()[0]
          : null;
        setError(firstFieldError ?? err.message);
      } else {
        setError("خطا در ذخیره دروس");
      }
    } finally {
      setSaving(false);
    }
  };

  const toggleBranch = (branchId: number) => {
    if (!card || card.kind === "official") return;
    const exists = card.branches.some((b) => b.id === branchId);
    const next = exists
      ? card.branches.filter((b) => b.id !== branchId)
      : [...card.branches, branches.find((b) => b.id === branchId)!].filter(Boolean);
    setCard({ ...card, branches: next });
  };

  const renderSubjectRow = (subject: SubjectItem, isExtra: boolean) => {
    const row = rowFor(subject.id);
    const coeffLabel =
      subject.field_coefficients && subject.field_coefficients.length > 0
        ? subject.field_coefficients
            .map((f) => `${f.study_field_name ?? "—"}: ${Number(f.coefficient).toLocaleString("fa-IR")}`)
            .join(" · ")
        : subject.coefficient != null
          ? `ضریب ${subject.coefficient.toLocaleString("fa-IR")}`
          : null;
    return (
      <div key={`${selectedGradeId}-${subject.id}`} className="rounded-xl border border-[var(--border)]">
        <div className="flex items-center gap-3 px-3 py-2">
          <input
            type="checkbox"
            checked={row.included}
            onChange={(e) => upsertRow(subject.id, { included: e.target.checked })}
          />
          <SubjectAvatar name={subject.name} imageUrl={subject.image_url} size="sm" />
          <div className="flex-1 text-sm font-medium">
            {subject.name}
            {isExtra ? (
              <span className="mr-2 rounded-full bg-amber-100 px-2 py-0.5 text-[10px] text-amber-800">
                فوق‌العاده
              </span>
            ) : null}
            {coeffLabel ? (
              <div className="text-xs font-normal text-[var(--muted)]">{coeffLabel}</div>
            ) : null}
          </div>
        </div>
      </div>
    );
  };

  if (!card) {
    return error ? <Alert tone="error">{error}</Alert> : <PageContentSkeleton rows={6} />;
  }

  return (
    <div className="space-y-4">
      {error ? <Alert tone="error">{error}</Alert> : null}
      {success ? <Alert tone="success">{success}</Alert> : null}

      <div className="flex flex-wrap gap-2">
        <Link href={`/academic/report-cards/${card.id}/analytics`}>
          <Button variant="secondary">نمودارهای تحلیلی</Button>
        </Link>
        <Button onClick={() => void saveTemplate()} disabled={saving}>ثبت اطلاعات</Button>
      </div>

      <section className="space-y-3 rounded-2xl border border-[var(--border)] bg-white p-4">
        <h2 className="font-bold text-primary">اطلاعات کلی</h2>
        <div className="grid gap-3 md:grid-cols-2">
          <Field label="عنوان کارنامه">
            <Input value={card.name} onChange={(e) => updateCardField("name", e.target.value)} />
          </Field>
          <Field label="توضیحات پاورقی کوتاه">
            <Input
              value={card.footer_note ?? ""}
              onChange={(e) => updateCardField("footer_note", e.target.value)}
            />
          </Field>
          <Field label="حداقل نمره">
            <Input
              type="number"
              value={String(card.min_score)}
              onChange={(e) => updateCardField("min_score", e.target.value)}
            />
          </Field>
          <Field label="حداکثر نمره">
            <Input
              type="number"
              value={String(card.max_score)}
              onChange={(e) => updateCardField("max_score", e.target.value)}
            />
          </Field>
          <Field label="نوع گرد کردن">
            <select
              className="w-full rounded-xl border border-[var(--border)] px-3 py-2 text-sm"
              value={card.rounding_mode}
              onChange={(e) => updateCardField("rounding_mode", e.target.value)}
            >
              <option value="up">به بالا</option>
              <option value="down">به پایین</option>
              <option value="nearest">نزدیک‌ترین</option>
              <option value="none">بدون گرد کردن</option>
            </select>
          </Field>
        </div>
        <Field label="توضیحات بالای کارنامه">
          <textarea
            className="min-h-20 w-full rounded-xl border border-[var(--border)] px-3 py-2 text-sm"
            value={card.header_text ?? ""}
            onChange={(e) => updateCardField("header_text", e.target.value)}
          />
        </Field>
        <Field label="توضیحات پایین کارنامه">
          <textarea
            className="min-h-20 w-full rounded-xl border border-[var(--border)] px-3 py-2 text-sm"
            value={card.footer_text ?? ""}
            onChange={(e) => updateCardField("footer_text", e.target.value)}
          />
        </Field>

        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
          {(
            (card.kind === "official"
              ? ([
                  ["is_visible", "نمایش کارنامه"],
                  ["show_average", "نمایش میانگین"],
                  ["show_gpa", "نمایش معدل"],
                  ["show_discipline", "نمایش نمره انضباط"],
                  ["is_active", "فعال"],
                ] as const)
              : ([
                  ["is_visible", "نمایش کارنامه"],
                  ["show_average", "نمایش میانگین"],
                  ["show_gpa", "نمایش معدل"],
                  ["show_descriptive", "نمایش توصیفی نمرات"],
                  ["show_discipline", "نمایش نمره انضباط"],
                  ["show_discipline_descriptive", "نمایش توصیفی انضباط"],
                  ["is_active", "فعال"],
                ] as const)
            )
          ).map(([key, label]) => (
            <label key={key} className="flex items-center justify-between rounded-xl border border-[var(--border)] px-3 py-2 text-sm">
              <span>{label}</span>
              <input
                type="checkbox"
                checked={Boolean(card[key])}
                onChange={(e) => updateCardField(key, e.target.checked)}
              />
            </label>
          ))}
        </div>

        {card.kind !== "official" ? (
          <Field label="مدارس">
            <div className="grid max-h-40 gap-2 overflow-auto rounded-xl border border-[var(--border)] p-3 sm:grid-cols-2">
              {branches.map((b) => (
                <label key={b.id} className="flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={card.branches.some((x) => x.id === b.id)}
                    onChange={() => toggleBranch(b.id)}
                  />
                  {b.name}
                </label>
              ))}
            </div>
          </Field>
        ) : (
          <p className="text-xs text-[var(--muted)]">کارنامه رسمی برای کل هلدینگ است.</p>
        )}

        <Field label="نمودارها">
          <div className="grid gap-2 sm:grid-cols-2">
            {CHART_OPTIONS.map((c) => (
              <label key={c.key} className="flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={(card.enabled_charts ?? []).includes(c.key)}
                  onChange={() => {
                    const cur = card.enabled_charts ?? [];
                    const next = cur.includes(c.key)
                      ? cur.filter((x) => x !== c.key)
                      : [...cur, c.key];
                    updateCardField("enabled_charts", next as ChartKey[]);
                  }}
                />
                {c.label}
              </label>
            ))}
          </div>
        </Field>
      </section>

      {card.kind === "composite" ? (
        <section className="rounded-2xl border border-[var(--border)] bg-white p-4">
          <h2 className="mb-2 font-bold text-primary">کارنامه‌های ترکیب‌شده</h2>
          <ul className="space-y-1 text-sm">
            {card.composite_items.map((item) => (
              <li key={item.id}>
                <Link className="text-primary underline" href={`/academic/report-cards/${item.source_report_card_id}`}>
                  {item.source?.name ?? `#${item.source_report_card_id}`}
                </Link>
              </li>
            ))}
          </ul>
        </section>
      ) : null}

      <section className="space-y-3 rounded-2xl border border-[var(--border)] bg-white p-4">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <div>
            <h2 className="font-bold text-primary">دروس</h2>
            <p className="mt-1 text-xs text-[var(--muted)]">
              دروس رسمی از برنامه درسی پایه؛ در کارنامه غیررسمی می‌توانید دروس فوق‌العاده هم اضافه کنید.
            </p>
          </div>
          <select
            value={selectedGradeId ?? ""}
            onChange={(e) => setSelectedGradeId(Number(e.target.value))}
            className="rounded-xl border border-[var(--border)] px-3 py-2 text-sm"
          >
            {grades.map((g) => (
              <option key={g.id} value={g.id}>{g.name}</option>
            ))}
          </select>
        </div>

        {selectedGrade ? (
          <div className="rounded-xl border border-primary/20 bg-primary/5 px-3 py-2 text-sm">
            انتخاب دروس پایه <span className="font-bold text-primary">{selectedGrade.name}</span>
            <span className="mr-2 text-[var(--muted)]">
              · {selectedCountForGrade.toLocaleString("fa-IR")} درس انتخاب‌شده
            </span>
          </div>
        ) : null}

        <div className="space-y-2">
          {!selectedGradeId ? (
            <p className="text-sm text-[var(--muted)]">ابتدا یک پایه انتخاب کنید.</p>
          ) : officialSubjects.length === 0 && extraSubjects.length === 0 ? (
            <div className="text-sm text-[var(--muted)]">
              درسی برای این پایه تعریف نشده.
              {" "}
              <Link href="/academic/curriculum" className="text-primary underline">
                برنامه درسی پایه
              </Link>
              {card.kind === "unofficial" ? (
                <>
                  {" · "}
                  <Link href="/academic/curriculum/extras" className="text-primary underline">
                    دروس فوق‌العاده
                  </Link>
                </>
              ) : null}
            </div>
          ) : null}

          {selectedGradeId && officialSubjects.length > 0 ? (
            <div className="mb-2 text-xs font-semibold text-primary">دروس رسمی پایه</div>
          ) : null}
          {selectedGradeId
            ? officialSubjects.map((subject) => renderSubjectRow(subject, false))
            : null}

          {selectedGradeId && card.kind === "unofficial" && extraSubjects.length > 0 ? (
            <>
              <div className="mb-2 mt-4 text-xs font-semibold text-amber-700">دروس فوق‌العاده (اختیاری)</div>
              {extraSubjects.map((subject) => renderSubjectRow(subject, true))}
            </>
          ) : null}
        </div>

        <Button onClick={() => void saveSubjects()} disabled={saving || !selectedGradeId}>
          ذخیره دروس پایه {selectedGrade?.name ?? ""}
        </Button>
      </section>

      <section className="rounded-2xl border border-[var(--border)] bg-white p-4">
        <h2 className="mb-3 font-bold text-primary">هشدارها</h2>
        <ReportCardWarningsPanel cardId={card.id} />
      </section>
    </div>
  );
}
