"use client";

import { useEffect, useState } from "react";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input, Select, Textarea } from "@/components/ui/Field";
import { PersianDatePicker } from "@/components/ui/PersianDatePicker";
import { AssignmentTemplatePicker } from "@/components/teacher/AssignmentTemplatePicker";
import {
  CATEGORY_OPTIONS,
  OUTPUT_OPTIONS,
  STEP_TYPE_OPTIONS,
  deriveAssignmentEndsAt,
  emptyStep,
  type AssignmentEditPayload,
  type OutputFormat,
  type StepDraft,
  type StepType,
} from "@/components/teacher/assignment-editor-types";
import {
  StepAttachmentsEditor,
  uploadPendingStepAttachments,
} from "@/components/teacher/StepAttachmentsEditor";
import { ApiError, apiGet, apiPatch, apiPost, apiPut } from "@/lib/api";

export type { AssignmentEditPayload, OutputFormat, StepDraft, StepType } from "@/components/teacher/assignment-editor-types";
export { categoryLabel } from "@/components/teacher/assignment-editor-types";

interface CreatedAssignment {
  id: number;
  steps?: Array<{ id: number; sort_order: number }>;
}

export function AssignmentEditorForm({
  classRoomId,
  subjectId,
  assignment,
  onCancel,
  onSaved,
}: {
  classRoomId: number;
  subjectId?: number | null;
  assignment?: AssignmentEditPayload | null;
  onCancel: () => void;
  onSaved: () => void;
}) {
  const [title, setTitle] = useState("");
  const [instructions, setInstructions] = useState("");
  const [maxScore, setMaxScore] = useState("20");
  const [category, setCategory] = useState("homework");
  const [steps, setSteps] = useState<StepDraft[]>([emptyStep({ title: "مرحله ۱" })]);
  const [saving, setSaving] = useState(false);
  const [loadingSteps, setLoadingSteps] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [templateOpen, setTemplateOpen] = useState(false);

  useEffect(() => {
    const reset = async () => {
      setError(null);
      if (assignment) {
        setTitle(assignment.title);
        setInstructions(assignment.instructions ?? "");
        setMaxScore(String(assignment.max_score ?? 20));
        setCategory(assignment.category ?? "homework");
        setLoadingSteps(true);
        try {
          const remote = await apiGet<
            Array<{
              id: number;
              title: string;
              instructions?: string | null;
              step_type: StepType;
              content_url?: string | null;
              content_attachments?: StepDraft["content_attachments"] | null;
              starts_at?: string | null;
              ends_at?: string | null;
              auto_check: boolean;
              required_outputs?: OutputFormat[] | null;
              allow_late_submission: boolean;
              late_penalty_percent?: number;
              max_score?: number | string | null;
            }>
          >(`/assignments/${assignment.id}/steps`);
          setSteps(
            remote.length
              ? remote.map((s) =>
                  emptyStep({
                    id: s.id,
                    title: s.title,
                    instructions: s.instructions ?? "",
                    step_type: s.step_type,
                    content_url: s.content_url ?? "",
                    content_attachments: s.content_attachments ?? [],
                    starts_at: s.starts_at ? s.starts_at.slice(0, 10) : "",
                    ends_at: s.ends_at ? s.ends_at.slice(0, 10) : "",
                    auto_check: s.auto_check,
                    required_outputs: s.required_outputs?.length
                      ? s.required_outputs
                      : s.step_type === "submit"
                        ? ["text"]
                        : [],
                    allow_late_submission: s.allow_late_submission,
                    late_penalty_percent: String(s.late_penalty_percent ?? 0),
                    max_score: String(s.max_score ?? assignment.max_score ?? 20),
                  }),
                )
              : [emptyStep({ title: assignment.title, max_score: String(assignment.max_score ?? 20) })],
          );
        } catch (err) {
          setError(err instanceof ApiError ? err.message : "خطا در بارگذاری مراحل");
          setSteps([emptyStep({ title: assignment.title })]);
        } finally {
          setLoadingSteps(false);
        }
      } else {
        setTitle("");
        setInstructions("");
        setMaxScore("20");
        setCategory("homework");
        setSteps([emptyStep({ title: "مرحله ۱" })]);
      }
    };

    void reset();
  }, [assignment]);

  const updateStep = (index: number, patch: Partial<StepDraft>) => {
    setSteps((prev) => prev.map((s, i) => (i === index ? { ...s, ...patch } : s)));
  };

  const toggleOutput = (index: number, format: OutputFormat) => {
    setSteps((prev) =>
      prev.map((s, i) => {
        if (i !== index) return s;
        const has = s.required_outputs.includes(format);
        const next = has
          ? s.required_outputs.filter((f) => f !== format)
          : [...s.required_outputs, format];
        return { ...s, required_outputs: next };
      }),
    );
  };

  const moveStep = (index: number, dir: -1 | 1) => {
    setSteps((prev) => {
      const next = [...prev];
      const target = index + dir;
      if (target < 0 || target >= next.length) return prev;
      [next[index], next[target]] = [next[target], next[index]];
      return next;
    });
  };

  const buildStepsPayload = () =>
    steps.map((s) => ({
      id: s.id,
      title: s.title.trim(),
      instructions: s.instructions.trim() || null,
      step_type: s.step_type,
      content_url: s.content_url.trim() || null,
      content_attachments: s.content_attachments.length ? s.content_attachments : null,
      starts_at: s.starts_at || null,
      ends_at: s.ends_at,
      auto_check: s.auto_check || s.step_type === "auto_complete" || s.step_type === "content",
      required_outputs:
        s.step_type === "submit" || s.step_type === "quiz"
          ? s.required_outputs.length
            ? s.required_outputs
            : ["text"]
          : [],
      allow_late_submission: s.allow_late_submission,
      late_penalty_percent: Number(s.late_penalty_percent) || 0,
      max_score: s.max_score === "" ? null : Number(s.max_score),
    }));

  const uploadPendingForSteps = async (savedSteps: Array<{ id: number; sort_order: number }>) => {
    const ordered = [...savedSteps].sort((a, b) => a.sort_order - b.sort_order);
    for (let index = 0; index < steps.length; index += 1) {
      const pending = steps[index]?.pending_attachments ?? [];
      const stepId = ordered[index]?.id;
      if (stepId && pending.length) {
        await uploadPendingStepAttachments(stepId, pending);
      }
    }
  };

  const save = async () => {
    if (!title.trim()) {
      setError("عنوان تکلیف الزامی است.");
      return;
    }
    if (steps.some((s) => !s.title.trim())) {
      setError("عنوان همه مراحل الزامی است.");
      return;
    }
    if (steps.some((s) => !s.ends_at)) {
      setError("موعد پایان همه مراحل الزامی است.");
      return;
    }
    setSaving(true);
    setError(null);
    try {
      const derivedEndsAt = deriveAssignmentEndsAt(steps);
      const body = {
        title: title.trim(),
        instructions: instructions.trim() || null,
        max_score: Number(maxScore) || 20,
        category,
        ends_at: derivedEndsAt,
        subject_id: subjectId ?? null,
      };
      const stepsPayload = buildStepsPayload();

      if (assignment) {
        await apiPatch(`/assignments/${assignment.id}`, body);
        const savedSteps = await apiPut<Array<{ id: number; sort_order: number }>>(
          `/assignments/${assignment.id}/steps`,
          { steps: stepsPayload },
        );
        await uploadPendingForSteps(savedSteps);
      } else {
        const created = await apiPost<CreatedAssignment>("/assignments", {
          context_type: "class_room",
          context_id: classRoomId,
          ...body,
          steps: stepsPayload.map((step) => {
            const rest = { ...step };
            delete (rest as { id?: number }).id;
            return rest;
          }),
        });
        if (created.steps?.length) {
          await uploadPendingForSteps(created.steps);
        }
      }
      onSaved();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ذخیره تکلیف");
    } finally {
      setSaving(false);
    }
  };

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

      <section className="rounded-2xl border border-[var(--border)] bg-white p-5 shadow-sm">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-2">
          <h3 className="text-lg font-bold">اطلاعات تکلیف</h3>
          <Button variant="secondary" className="text-sm" onClick={() => setTemplateOpen(true)}>
            استفاده از تکلیف قبلی
          </Button>
        </div>
        <div className="space-y-3">
          <Field label="عنوان">
            <Input value={title} onChange={(e) => setTitle(e.target.value)} />
          </Field>
          <Field label="دستورالعمل کلی (اختیاری)">
            <Textarea
              value={instructions}
              onChange={(e) => setInstructions(e.target.value)}
              rows={3}
            />
          </Field>
          <div className="grid grid-cols-2 gap-3">
            <Field label="بارم پیش‌فرض (اختیاری)">
              <Input
                type="number"
                min={0}
                value={maxScore}
                onChange={(e) => setMaxScore(e.target.value)}
              />
            </Field>
            <Field label="دسته">
              <Select value={category} onChange={(e) => setCategory(e.target.value)}>
                {CATEGORY_OPTIONS.map(([value, label]) => (
                  <option key={value} value={value}>
                    {label}
                  </option>
                ))}
              </Select>
            </Field>
          </div>
        </div>
      </section>

      <section className="rounded-2xl border border-[var(--border)] bg-white p-5 shadow-sm">
        <div className="mb-4 flex items-center justify-between gap-2">
          <div>
            <h3 className="text-lg font-bold">مراحل تمرین</h3>
            <p className="text-xs text-[var(--muted)]">
              ترتیب مراحل مسیر پیشرفت فراگیر را مشخص می‌کند. موعد پایان هر مرحله الزامی است.
            </p>
          </div>
          <Button
            variant="secondary"
            className="text-sm"
            onClick={() =>
              setSteps((prev) => [...prev, emptyStep({ title: `مرحله ${prev.length + 1}` })])
            }
          >
            + مرحله
          </Button>
        </div>

        {loadingSteps ? (
          <p className="text-sm text-[var(--muted)]">در حال بارگذاری مراحل…</p>
        ) : (
          <div className="space-y-3">
            {steps.map((step, index) => (
              <div
                key={step.id ?? `new-${index}`}
                className="rounded-xl border border-[var(--border)] bg-slate-50/60 p-4"
              >
                <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
                  <span className="text-sm font-medium">مرحله {index + 1}</span>
                  <div className="flex gap-1">
                    <Button
                      variant="ghost"
                      className="px-2 py-1 text-xs"
                      onClick={() => moveStep(index, -1)}
                      disabled={index === 0}
                    >
                      بالا
                    </Button>
                    <Button
                      variant="ghost"
                      className="px-2 py-1 text-xs"
                      onClick={() => moveStep(index, 1)}
                      disabled={index === steps.length - 1}
                    >
                      پایین
                    </Button>
                    <Button
                      variant="ghost"
                      className="px-2 py-1 text-xs text-red-600"
                      onClick={() =>
                        setSteps((prev) => (prev.length <= 1 ? prev : prev.filter((_, i) => i !== index)))
                      }
                      disabled={steps.length <= 1}
                    >
                      حذف
                    </Button>
                  </div>
                </div>

                <div className="space-y-3">
                  <Field label="عنوان مرحله">
                    <Input
                      value={step.title}
                      onChange={(e) => updateStep(index, { title: e.target.value })}
                    />
                  </Field>
                  <div className="grid gap-3 sm:grid-cols-2">
                    <Field label="نوع">
                      <Select
                        value={step.step_type}
                        onChange={(e) => {
                          const step_type = e.target.value as StepType;
                          updateStep(index, {
                            step_type,
                            auto_check:
                              step_type === "content" || step_type === "auto_complete"
                                ? true
                                : step.auto_check,
                            required_outputs:
                              step_type === "submit" || step_type === "quiz"
                                ? step.required_outputs.length
                                  ? step.required_outputs
                                  : ["text"]
                                : [],
                          });
                        }}
                      >
                        {STEP_TYPE_OPTIONS.map(([value, label]) => (
                          <option key={value} value={value}>
                            {label}
                          </option>
                        ))}
                      </Select>
                    </Field>
                    <Field label="موعد پایان مرحله *">
                      <PersianDatePicker
                        value={step.ends_at}
                        onChange={(v) => updateStep(index, { ends_at: v })}
                      />
                    </Field>
                  </div>
                  <Field label="شروع مرحله (اختیاری)">
                    <PersianDatePicker
                      value={step.starts_at}
                      onChange={(v) => updateStep(index, { starts_at: v })}
                    />
                  </Field>
                  <Field label="دستورالعمل / توضیح">
                    <Textarea
                      rows={2}
                      value={step.instructions}
                      onChange={(e) => updateStep(index, { instructions: e.target.value })}
                    />
                  </Field>
                  <Field label="لینک محتوا (اختیاری)">
                    <Input
                      value={step.content_url}
                      onChange={(e) => updateStep(index, { content_url: e.target.value })}
                      placeholder="https://…"
                    />
                  </Field>

                  <StepAttachmentsEditor
                    stepId={step.id}
                    attachments={step.content_attachments}
                    pending={step.pending_attachments}
                    disabled={saving || loadingSteps}
                    onAttachmentsChange={(next) => updateStep(index, { content_attachments: next })}
                    onPendingChange={(next) => updateStep(index, { pending_attachments: next })}
                  />

                  {(step.step_type === "submit" || step.step_type === "quiz") && (
                    <>
                      <div>
                        <span className="mb-1.5 block text-sm font-medium">خروجی‌های الزامی</span>
                        <div className="flex flex-wrap gap-3">
                          {OUTPUT_OPTIONS.map(([value, label]) => (
                            <label key={value} className="flex items-center gap-1.5 text-sm">
                              <input
                                type="checkbox"
                                checked={step.required_outputs.includes(value)}
                                onChange={() => toggleOutput(index, value)}
                              />
                              {label}
                            </label>
                          ))}
                        </div>
                      </div>
                      <label className="flex items-center gap-2 text-sm">
                        <input
                          type="checkbox"
                          checked={step.auto_check}
                          onChange={(e) => updateStep(index, { auto_check: e.target.checked })}
                        />
                        تکمیل بدون تصحیح معلم (auto_check)
                      </label>
                      <div className="grid gap-3 sm:grid-cols-3">
                        <Field label="بارم مرحله">
                          <Input
                            type="number"
                            min={0}
                            value={step.max_score}
                            onChange={(e) => updateStep(index, { max_score: e.target.value })}
                          />
                        </Field>
                        <label className="flex items-end gap-2 pb-2 text-sm sm:col-span-1">
                          <input
                            type="checkbox"
                            checked={step.allow_late_submission}
                            onChange={(e) =>
                              updateStep(index, { allow_late_submission: e.target.checked })
                            }
                          />
                          ارسال با تأخیر
                        </label>
                        <Field label="جریمه تأخیر ٪ (هنگام نمره‌دهی)">
                          <Input
                            type="number"
                            min={0}
                            max={100}
                            disabled={!step.allow_late_submission}
                            value={step.late_penalty_percent}
                            onChange={(e) =>
                              updateStep(index, { late_penalty_percent: e.target.value })
                            }
                          />
                        </Field>
                      </div>
                      <p className="text-xs text-[var(--muted)]">
                        جریمه تأخیر هنگام ارسال اعمال نمی‌شود؛ معلم هنگام نمره‌دهی می‌تواند آن را
                        لحاظ کند.
                      </p>
                    </>
                  )}
                </div>
              </div>
            ))}
          </div>
        )}
      </section>

      <div className="flex justify-end gap-2">
        <Button variant="secondary" onClick={onCancel} disabled={saving}>
          انصراف
        </Button>
        <Button onClick={save} loading={saving || loadingSteps}>
          {assignment ? "ذخیره تغییرات" : "ایجاد تکلیف"}
        </Button>
      </div>

      {templateOpen ? (
        <AssignmentTemplatePicker
          excludeAssignmentId={assignment?.id}
          onClose={() => setTemplateOpen(false)}
          onApply={(payload) => {
            setTitle(payload.title);
            setInstructions(payload.instructions);
            setMaxScore(payload.maxScore);
            setCategory(payload.category);
            setSteps(payload.steps.length ? payload.steps : [emptyStep({ title: "مرحله ۱" })]);
            setError(null);
          }}
        />
      ) : null}
    </div>
  );
}
