"use client";

import { useEffect, useRef, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { QuizTemplate, Question, QuestionType, SubQuestion } from "@/types/quiz";

function generateId(): string {
  return Math.random().toString(36).substring(2, 9);
}

function createEmptyQuestion(type: QuestionType): Question {
  const id = generateId();
  if (type === "true-false") {
    return {
      id,
      type,
      text: "",
      options: [
        { id: "true", label: "True" },
        { id: "false", label: "False" },
      ],
      correctAnswers: [],
    };
  }
  if (type === "open-ended") {
    return { id, type, text: "", options: [], correctAnswers: [""] };
  }
  if (type === "multiple-dropdown") {
    return {
      id,
      type,
      text: "",
      options: [],
      correctAnswers: [],
      subQuestions: [
        {
          id: generateId(),
          text: "",
          options: [
            { id: generateId(), label: "" },
            { id: generateId(), label: "" },
          ],
          correctOptionId: "",
        },
      ],
    };
  }
  return {
    id,
    type,
    text: "",
    options: [
      { id: generateId(), label: "" },
      { id: generateId(), label: "" },
    ],
    correctAnswers: [],
  };
}

function ImageInput({
  value,
  onChange,
  placeholder,
  className,
  variant = "compact",
}: {
  value: string;
  onChange: (url: string) => void;
  placeholder?: string;
  className?: string;
  variant?: "compact" | "full";
}) {
  const fileRef = useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = useState(false);

  async function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    const form = new FormData();
    form.append("file", file);
    const res = await fetch("/api/admin/upload", { method: "POST", body: form });
    const data = await res.json();
    if (data.url) onChange(data.url);
    setUploading(false);
    e.target.value = "";
  }

  const controls = (
    <>
      <input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder || "Image URL (optional)"}
        className="flex-1 px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white text-sm"
      />
      <input type="file" ref={fileRef} onChange={handleFile} accept="image/*" className="hidden" />
      <button
        type="button"
        onClick={() => fileRef.current?.click()}
        disabled={uploading}
        className="px-2 py-1.5 text-xs bg-gray-600 rounded hover:bg-gray-500 disabled:opacity-50 whitespace-nowrap"
      >
        {uploading ? "..." : "Upload"}
      </button>
    </>
  );

  if (variant === "full") {
    return (
      <div className={`space-y-2 ${className || ""}`}>
        {value && (
          // eslint-disable-next-line @next/next/no-img-element
          <img
            src={value}
            alt=""
            className="w-full max-h-56 object-contain rounded border border-gray-600 bg-gray-700"
          />
        )}
        <div className="flex items-center gap-2">{controls}</div>
      </div>
    );
  }

  return (
    <div className={`flex items-center gap-2 ${className || ""}`}>
      {value ? (
        // eslint-disable-next-line @next/next/no-img-element
        <img
          src={value}
          alt=""
          className="w-10 h-10 object-contain rounded border border-gray-600 bg-gray-700 flex-shrink-0"
        />
      ) : (
        <div className="w-10 h-10 rounded border border-gray-600 bg-gray-700 flex-shrink-0" />
      )}
      {controls}
    </div>
  );
}

function CollapsibleImageInput({
  value,
  onChange,
  placeholder,
  variant = "compact",
}: {
  value: string;
  onChange: (url: string) => void;
  placeholder?: string;
  variant?: "compact" | "full";
}) {
  const [show, setShow] = useState(!!value);

  if (!show) {
    return (
      <button
        type="button"
        onClick={() => setShow(true)}
        className="text-xs text-blue-400 hover:text-blue-300"
      >
        + Add image
      </button>
    );
  }

  return (
    <div className="space-y-1">
      <ImageInput value={value} onChange={onChange} placeholder={placeholder} variant={variant} className="w-full" />
      <button
        type="button"
        onClick={() => { onChange(""); setShow(false); }}
        className="text-xs text-gray-500 hover:text-gray-400"
      >
        − Remove image
      </button>
    </div>
  );
}

function QuestionEditor({
  question,
  index,
  onChange,
  onDelete,
  onDuplicate,
  onMoveUp,
  onMoveDown,
  isFirst,
  isLast,
}: {
  question: Question;
  index: number;
  onChange: (q: Question) => void;
  onDelete: () => void;
  onDuplicate: () => void;
  onMoveUp: () => void;
  onMoveDown: () => void;
  isFirst: boolean;
  isLast: boolean;
}) {
  function updateText(text: string) {
    onChange({ ...question, text });
  }

  function updateImageUrl(imageUrl: string) {
    onChange({ ...question, imageUrl: imageUrl || undefined });
  }

  function updateType(type: QuestionType) {
    const newQ = createEmptyQuestion(type);
    newQ.id = question.id;
    newQ.text = question.text;
    onChange(newQ);
  }

  function updateOptionLabel(optionId: string, label: string) {
    onChange({
      ...question,
      options: question.options.map((o) =>
        o.id === optionId ? { ...o, label } : o
      ),
    });
  }

  function updateOptionImageUrl(optionId: string, imageUrl: string) {
    onChange({
      ...question,
      options: question.options.map((o) =>
        o.id === optionId ? { ...o, imageUrl: imageUrl || undefined } : o
      ),
    });
  }

  function addOption() {
    onChange({
      ...question,
      options: [...question.options, { id: generateId(), label: "" }],
    });
  }

  function removeOption(optionId: string) {
    onChange({
      ...question,
      options: question.options.filter((o) => o.id !== optionId),
      correctAnswers: question.correctAnswers.filter((a) => a !== optionId),
    });
  }

  function toggleCorrect(optionId: string) {
    if (question.type === "single-answer" || question.type === "dropdown" || question.type === "true-false") {
      onChange({ ...question, correctAnswers: [optionId] });
    } else {
      const has = question.correctAnswers.includes(optionId);
      onChange({
        ...question,
        correctAnswers: has
          ? question.correctAnswers.filter((a) => a !== optionId)
          : [...question.correctAnswers, optionId],
      });
    }
  }

  function addSubQuestion() {
    onChange({
      ...question,
      subQuestions: [
        ...(question.subQuestions || []),
        {
          id: generateId(),
          text: "",
          options: [
            { id: generateId(), label: "" },
            { id: generateId(), label: "" },
          ],
          correctOptionId: "",
        },
      ],
    });
  }

  function updateSubQuestion(subId: string, updates: Partial<SubQuestion>) {
    onChange({
      ...question,
      subQuestions: (question.subQuestions || []).map((sq) =>
        sq.id === subId ? { ...sq, ...updates } : sq
      ),
    });
  }

  function removeSubQuestion(subId: string) {
    onChange({
      ...question,
      subQuestions: (question.subQuestions || []).filter((sq) => sq.id !== subId),
    });
  }

  const typeLabels: Record<QuestionType, string> = {
    "true-false": "True / False",
    "single-answer": "Single Answer",
    "multiple-answer": "Multiple Answers",
    dropdown: "Dropdown",
    "multiple-dropdown": "Multiple Dropdown",
    "open-ended": "Open Ended",
  };

  return (
    <div className={`p-4 rounded-lg space-y-3 ${question.hidden ? "bg-gray-800/50 border border-gray-700 opacity-60" : "bg-gray-800"}`}>
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="text-sm text-gray-400 font-medium">
            Question {index + 1}
          </span>
          {question.hidden && (
            <span className="text-xs bg-gray-700 text-gray-400 px-1.5 py-0.5 rounded">Hidden</span>
          )}
        </div>
        <div className="flex gap-1">
          <button
            onClick={onMoveUp}
            disabled={isFirst}
            className="px-2 py-1 text-xs bg-gray-700 rounded hover:bg-gray-600 disabled:opacity-30"
          >
            ↑
          </button>
          <button
            onClick={onMoveDown}
            disabled={isLast}
            className="px-2 py-1 text-xs bg-gray-700 rounded hover:bg-gray-600 disabled:opacity-30"
          >
            ↓
          </button>
          <button
            onClick={onDuplicate}
            className="px-2 py-1 text-xs bg-gray-600 rounded hover:bg-gray-500"
          >
            Duplicate
          </button>
          <button
            onClick={() => onChange({ ...question, hidden: !question.hidden })}
            className={`px-2 py-1 text-xs rounded ${question.hidden ? "bg-yellow-700 hover:bg-yellow-600" : "bg-gray-700 hover:bg-gray-600"}`}
          >
            {question.hidden ? "Unhide" : "Hide"}
          </button>
          <button
            onClick={onDelete}
            className="px-2 py-1 text-xs bg-red-600 rounded hover:bg-red-700"
          >
            Delete
          </button>
        </div>
      </div>

      <div className="flex gap-3">
        <select
          value={question.type}
          onChange={(e) => updateType(e.target.value as QuestionType)}
          className="px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white text-sm"
        >
          {Object.entries(typeLabels).map(([value, label]) => (
            <option key={value} value={value}>
              {label}
            </option>
          ))}
        </select>
      </div>

      <textarea
        placeholder="Question text"
        value={question.text}
        onChange={(e) => updateText(e.target.value)}
        className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white resize-none"
        rows={2}
      />

      <CollapsibleImageInput
        value={question.imageUrl || ""}
        onChange={updateImageUrl}
        placeholder="Question image URL (optional)"
        variant="full"
      />

      {question.type === "multiple-dropdown" ? (
        <div className="space-y-3">
          <span className="text-xs text-gray-400">
            Sub-questions (each with its own dropdown choices and correct answer):
          </span>
          {(question.subQuestions || []).map((sq, si) => (
            <div key={sq.id} className="p-3 bg-gray-700 rounded space-y-2">
              <div className="flex items-center gap-2">
                <span className="text-xs text-gray-400 flex-shrink-0">#{si + 1}</span>
                <input
                  type="text"
                  placeholder="Sub-question text"
                  value={sq.text}
                  onChange={(e) => updateSubQuestion(sq.id, { text: e.target.value })}
                  className="flex-1 px-3 py-1.5 bg-gray-600 border border-gray-500 rounded text-white text-sm"
                />
                {(question.subQuestions || []).length > 1 && (
                  <button
                    onClick={() => removeSubQuestion(sq.id)}
                    className="text-gray-400 hover:text-red-400 text-sm"
                  >
                    ✕
                  </button>
                )}
              </div>
              <CollapsibleImageInput
                value={sq.imageUrl || ""}
                onChange={(url) => updateSubQuestion(sq.id, { imageUrl: url || undefined })}
                placeholder="Sub-question image URL (optional)"
              />

              <div className="pl-6 space-y-1">
                <span className="text-xs text-gray-400">Choices:</span>
                {(sq.options || []).map((opt) => (
                  <div key={opt.id} className="flex items-center gap-2">
                    <button
                      type="button"
                      onClick={() => updateSubQuestion(sq.id, { correctOptionId: opt.id })}
                      className={`w-5 h-5 rounded-full flex items-center justify-center border flex-shrink-0 ${
                        sq.correctOptionId === opt.id
                          ? "bg-green-600 border-green-500"
                          : "border-gray-500 bg-gray-600"
                      }`}
                    >
                      {sq.correctOptionId === opt.id && (
                        <span className="text-xs">✓</span>
                      )}
                    </button>
                    <input
                      type="text"
                      placeholder="Choice text"
                      value={opt.label}
                      onChange={(e) => {
                        const newOpts = (sq.options || []).map((o) =>
                          o.id === opt.id ? { ...o, label: e.target.value } : o
                        );
                        updateSubQuestion(sq.id, { options: newOpts });
                      }}
                      className="flex-1 px-2 py-1 bg-gray-600 border border-gray-500 rounded text-white text-sm"
                    />
                    {(sq.options || []).length > 2 && (
                      <button
                        onClick={() => {
                          const newOpts = (sq.options || []).filter((o) => o.id !== opt.id);
                          const updates: Partial<SubQuestion> = { options: newOpts };
                          if (sq.correctOptionId === opt.id) updates.correctOptionId = "";
                          updateSubQuestion(sq.id, updates);
                        }}
                        className="text-gray-400 hover:text-red-400 text-sm"
                      >
                        ✕
                      </button>
                    )}
                  </div>
                ))}
                <button
                  onClick={() => {
                    const newOpts = [...(sq.options || []), { id: generateId(), label: "" }];
                    updateSubQuestion(sq.id, { options: newOpts });
                  }}
                  className="text-xs text-blue-400 hover:text-blue-300"
                >
                  + Add choice
                </button>
              </div>
            </div>
          ))}
          <button
            onClick={addSubQuestion}
            className="text-sm text-blue-400 hover:text-blue-300"
          >
            + Add sub-question
          </button>
        </div>
      ) : question.type === "open-ended" ? (
        <div className="space-y-2">
          <span className="text-xs text-gray-400">Expected answer (shown as hint in learning mode):</span>
          {question.correctAnswers.map((ans, i) => (
            <div key={i} className="flex items-center gap-2">
              <textarea
                value={ans}
                onChange={(e) => {
                  const updated = [...question.correctAnswers];
                  updated[i] = e.target.value;
                  onChange({ ...question, correctAnswers: updated });
                }}
                rows={2}
                className="flex-1 px-3 py-1.5 bg-gray-700 border border-gray-600 rounded text-white text-sm resize-none"
                placeholder="Expected answer text..."
              />
              {question.correctAnswers.length > 1 && (
                <button
                  onClick={() => onChange({ ...question, correctAnswers: question.correctAnswers.filter((_, j) => j !== i) })}
                  className="text-gray-500 hover:text-red-400 text-sm"
                >✕</button>
              )}
            </div>
          ))}
          <button
            onClick={() => onChange({ ...question, correctAnswers: [...question.correctAnswers, ""] })}
            className="text-sm text-blue-400 hover:text-blue-300"
          >+ Add alternative answer</button>
        </div>
      ) : (
      <div className="space-y-2">
        <span className="text-xs text-gray-400">
          Options (click radio/checkbox to mark correct answer):
        </span>
        {question.options.map((option) => (
          <div key={option.id} className="flex items-center gap-2">
            <button
              type="button"
              onClick={() => toggleCorrect(option.id)}
              className={`w-5 h-5 rounded flex items-center justify-center border ${
                question.correctAnswers.includes(option.id)
                  ? "bg-green-600 border-green-500"
                  : "border-gray-500 bg-gray-700"
              } ${
                question.type === "multiple-answer" ? "rounded" : "rounded-full"
              }`}
            >
              {question.correctAnswers.includes(option.id) && (
                <span className="text-xs">✓</span>
              )}
            </button>
            {question.type === "true-false" ? (
              <span className="text-sm text-gray-300">{option.label}</span>
            ) : (
              <div className="flex-1 space-y-1">
                <input
                  type="text"
                  placeholder="Option text"
                  value={option.label}
                  onChange={(e) => updateOptionLabel(option.id, e.target.value)}
                  className="w-full px-3 py-1.5 bg-gray-700 border border-gray-600 rounded text-white text-sm"
                />
                <CollapsibleImageInput
                  value={option.imageUrl || ""}
                  onChange={(url) => updateOptionImageUrl(option.id, url)}
                  placeholder="Option image URL (optional)"
                />
              </div>
            )}
            {question.type !== "true-false" && question.options.length > 2 && (
              <button
                onClick={() => removeOption(option.id)}
                className="text-gray-500 hover:text-red-400 text-sm"
              >
                ✕
              </button>
            )}
          </div>
        ))}
        {question.type !== "true-false" && (
          <button
            onClick={addOption}
            className="text-sm text-blue-400 hover:text-blue-300"
          >
            + Add option
          </button>
        )}
      </div>
      )}
    </div>
  );
}

export default function EditTemplatePage() {
  const params = useParams();
  const router = useRouter();
  const [template, setTemplate] = useState<QuizTemplate | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);

  useEffect(() => {
    fetch(`/api/templates/${params.id}`)
      .then((r) => r.json())
      .then((data) => {
        setTemplate(data);
        setLoading(false);
      });
  }, [params.id]);

  async function handleSave() {
    if (!template) return;
    setSaving(true);
    await fetch(`/api/templates/${template.id}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(template),
    });
    setSaving(false);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  const lastQuestionRef = useRef<HTMLDivElement>(null);
  const [scrollToNew, setScrollToNew] = useState(false);

  useEffect(() => {
    if (scrollToNew && lastQuestionRef.current) {
      lastQuestionRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
      setScrollToNew(false);
    }
  }, [scrollToNew, template?.questions.length]);

  function addQuestion(type: QuestionType) {
    if (!template) return;
    setTemplate({
      ...template,
      questions: [...template.questions, createEmptyQuestion(type)],
    });
    setScrollToNew(true);
  }

  function updateQuestion(index: number, question: Question) {
    if (!template) return;
    const questions = [...template.questions];
    questions[index] = question;
    setTemplate({ ...template, questions });
  }

  function deleteQuestion(index: number) {
    if (!template) return;
    setTemplate({
      ...template,
      questions: template.questions.filter((_, i) => i !== index),
    });
  }

  function duplicateQuestion(index: number) {
    if (!template) return;
    const original = template.questions[index];
    const clone: Question = {
      ...original,
      id: generateId(),
      options: original.options.map((o) => ({ ...o, id: generateId() })),
      subQuestions: original.subQuestions?.map((sq) => ({
        ...sq,
        id: generateId(),
        options: sq.options.map((o) => ({ ...o, id: generateId() })),
      })),
    };
    const questions = [...template.questions];
    questions.splice(index + 1, 0, clone);
    setTemplate({ ...template, questions });
  }

  function moveQuestion(index: number, direction: -1 | 1) {
    if (!template) return;
    const questions = [...template.questions];
    const newIndex = index + direction;
    if (newIndex < 0 || newIndex >= questions.length) return;
    [questions[index], questions[newIndex]] = [questions[newIndex], questions[index]];
    setTemplate({ ...template, questions });
  }

  if (loading || !template) {
    return (
      <div className="min-h-screen bg-gray-900 flex items-center justify-center">
        <p className="text-gray-400">Loading...</p>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-900 text-white">
      <header className="border-b border-gray-700 px-6 py-4 flex items-center justify-between sticky top-0 bg-gray-900 z-10">
        <div className="flex items-center gap-4">
          <button
            onClick={() => router.push("/admin")}
            className="text-gray-400 hover:text-white text-sm"
          >
            ← Back
          </button>
          <h1 className="text-xl font-bold">Edit: {template.title}</h1>
        </div>
        <div className="flex items-center gap-3">
          {saved && (
            <span className="text-green-400 text-sm">Saved!</span>
          )}
          <button
            onClick={handleSave}
            disabled={saving}
            className="px-4 py-2 bg-green-600 rounded-lg hover:bg-green-700 disabled:opacity-50 text-sm font-medium"
          >
            {saving ? "Saving..." : "Save"}
          </button>
        </div>
      </header>

      <div className="sticky top-[57px] z-10 bg-gray-900 border-b border-gray-700">
        <div className="max-w-3xl mx-auto px-6 py-4 space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-sm text-gray-400 mb-1">Title</label>
              <input
                type="text"
                value={template.title}
                onChange={(e) =>
                  setTemplate({ ...template, title: e.target.value })
                }
                className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white"
              />
            </div>
            <div>
              <label className="block text-sm text-gray-400 mb-1">
                Description
              </label>
              <input
                type="text"
                value={template.description}
                onChange={(e) =>
                  setTemplate({ ...template, description: e.target.value })
                }
                className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white"
              />
            </div>
          </div>

          <div className="flex items-center justify-between">
            <h2 className="font-semibold">
              Questions ({template.questions.length})
            </h2>
            <div className="flex gap-2">
              <button
                onClick={() => addQuestion("true-false")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + True/False
              </button>
              <button
                onClick={() => addQuestion("single-answer")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + Single
              </button>
              <button
                onClick={() => addQuestion("multiple-answer")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + Multiple
              </button>
              <button
                onClick={() => addQuestion("dropdown")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + Dropdown
              </button>
              <button
                onClick={() => addQuestion("multiple-dropdown")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + Multi Dropdown
              </button>
              <button
                onClick={() => addQuestion("open-ended")}
                className="px-3 py-1.5 bg-gray-700 rounded text-sm hover:bg-gray-600"
              >
                + Open Ended
              </button>
            </div>
          </div>
        </div>
      </div>

      <main className="max-w-3xl mx-auto p-6">
        <div className="space-y-4">
          {template.questions.map((q, i) => (
            <div key={q.id} ref={i === template.questions.length - 1 ? lastQuestionRef : undefined}>
              <QuestionEditor
                question={q}
                index={i}
                onChange={(updated) => updateQuestion(i, updated)}
                onDelete={() => deleteQuestion(i)}
                onDuplicate={() => duplicateQuestion(i)}
                onMoveUp={() => moveQuestion(i, -1)}
                onMoveDown={() => moveQuestion(i, 1)}
                isFirst={i === 0}
                isLast={i === template.questions.length - 1}
              />
            </div>
          ))}

          {template.questions.length === 0 && (
            <p className="text-gray-500 text-center py-8">
              No questions yet. Use the buttons above to add questions.
            </p>
          )}
        </div>
      </main>
    </div>
  );
}
