"use client";

import { ChangeEvent, FormEvent, useEffect, useMemo, useState } from "react";
import { apiFetch, apiUrl } from "@/app/lib/api-client";
import { mediaUrl } from "@/app/lib/media";

type SubmissionType = "ebook" | "video";

interface FormState {
  type: SubmissionType;
  title: string;
  subtitle: string;
  description: string;
  coverImage: string;
  mediaUrl: string;
  authorName: string;
  authorEmail: string;
  chaptersText: string;
}

interface ContentSubmissionModalProps {
  open: boolean;
  locale: string;
  onClose: () => void;
  submissionType?: SubmissionType;
}

const MB = 1024 * 1024;

const EMPTY_FORM: FormState = {
  type: "ebook",
  title: "",
  subtitle: "",
  description: "",
  coverImage: "",
  mediaUrl: "",
  authorName: "",
  authorEmail: "",
  chaptersText: "",
};

export default function ContentSubmissionModal({ open, locale, onClose, submissionType }: ContentSubmissionModalProps) {
  const isZh = locale === "zh";
  const initialType = submissionType || "ebook";
  const copy = useMemo(() => {
    let title = isZh ? "投稿电子书 / 访谈视频" : "Submit ebook / interview";
    if (submissionType === "ebook") {
      title = isZh ? "投稿电子书" : "Submit ebook";
    }
    if (submissionType === "video") {
      title = isZh ? "投稿访谈视频" : "Submit interview video";
    }

    return {
      title,
      close: isZh ? "关闭" : "Close",
      ebook: isZh ? "电子书" : "Ebook",
      video: isZh ? "访谈视频" : "Interview video",
      name: isZh ? "作者昵称" : "Author name",
      email: isZh ? "联系邮箱" : "Contact email",
      contentTitle: isZh ? "标题" : "Title",
      subtitle: isZh ? "一句话简介" : "Short subtitle",
      description: isZh ? "内容简介" : "Description",
      cover: isZh ? "封面图" : "Cover image",
      coverUrl: isZh ? "封面图 URL" : "Cover image URL",
      file: isZh ? "内容文件" : "Content file",
      fileUrl: isZh ? "电子书 PDF/EPUB 或视频直链" : "PDF/EPUB or direct video URL",
      chapters: isZh ? "目录 / 章节" : "Chapters",
      chaptersHint: isZh ? "每行一个章节，可选" : "One chapter per line, optional",
      uploadCover: isZh ? "上传封面" : "Upload cover",
      uploadFile: isZh ? "上传文件" : "Upload file",
      uploading: isZh ? "上传中..." : "Uploading...",
      submit: isZh ? "提交审核" : "Submit for review",
      submitting: isZh ? "提交中..." : "Submitting...",
      success: isZh ? "已提交，审核通过后会展示在首页。" : "Submitted. It will appear after review.",
      required: isZh ? "请填写标题、简介、封面、内容文件和联系邮箱。" : "Please complete title, description, cover, file and email.",
      uploadFailed: isZh ? "上传失败" : "Upload failed",
      fileTooLarge: isZh ? "文件过大" : "File too large",
      review: isZh ? "状态：待审核" : "Status: pending review",
    };
  }, [isZh, submissionType]);

  const [form, setForm] = useState<FormState>({ ...EMPTY_FORM, type: initialType });
  const [uploading, setUploading] = useState<"coverImage" | "mediaUrl" | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  useEffect(() => {
    if (open) {
      setMessage("");
      setError("");
      setForm((prev) => ({ ...prev, type: initialType }));
    }
  }, [open, initialType]);

  if (!open) return null;

  const set = <K extends keyof FormState>(key: K, value: FormState[K]) => {
    setForm((prev) => ({ ...prev, [key]: value }));
    setError("");
  };

  const mediaMaxSize = form.type === "video" ? 200 * MB : 100 * MB;
  const contentAccept =
    form.type === "video"
      ? "video/mp4,video/webm,video/quicktime"
      : "application/pdf,application/epub+zip,.pdf,.epub,.mobi,.azw3";

  async function uploadFile(event: ChangeEvent<HTMLInputElement>, target: "coverImage" | "mediaUrl") {
    const file = event.currentTarget.files?.[0];
    event.currentTarget.value = "";
    if (!file) return;

    const limit = target === "coverImage" ? 20 * MB : mediaMaxSize;
    if (file.size > limit) {
      setError(`${copy.fileTooLarge}，最大 ${Math.round(limit / MB)}MB`);
      return;
    }

    setUploading(target);
    setError("");
    try {
      const data = new FormData();
      data.append("file", file);
      const res = await fetch(apiUrl("/api/upload-media?purpose=content"), {
        method: "POST",
        body: data,
        credentials: "include",
      });
      const json = (await res.json().catch(() => ({}))) as { ok?: boolean; url?: string; detail?: string; error?: string };
      if (!res.ok || !json.ok || !json.url) {
        throw new Error(json.detail || json.error || copy.uploadFailed);
      }
      setForm((prev) => ({ ...prev, [target]: json.url || "" }));
    } catch (err) {
      setError(err instanceof Error ? err.message : copy.uploadFailed);
    } finally {
      setUploading(null);
    }
  }

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const title = form.title.trim();
    const description = form.description.trim();
    const coverImage = form.coverImage.trim();
    const mediaUrl = form.mediaUrl.trim();
    const authorEmail = form.authorEmail.trim();
    if (!title || !description || !coverImage || !mediaUrl || !authorEmail) {
      setError(copy.required);
      return;
    }

    setSubmitting(true);
    setError("");
    setMessage("");
    try {
      await apiFetch("/api/content/submissions", {
        method: "POST",
        body: JSON.stringify({
          type: form.type,
          title,
          subtitle: form.subtitle.trim(),
          description,
          coverImage,
          mediaUrl,
          authorName: form.authorName.trim(),
          authorEmail,
          chapters: form.chaptersText
            .split("\n")
            .map((line) => line.trim())
            .filter(Boolean)
            .map((line) => ({ title: line })),
        }),
      });
      setMessage(copy.success);
      setForm({ ...EMPTY_FORM, type: initialType });
    } catch (err) {
      setError(err instanceof Error ? err.message : "提交失败");
    } finally {
      setSubmitting(false);
    }
  }

  const busy = submitting || Boolean(uploading);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-3 py-5 backdrop-blur-sm" role="dialog" aria-modal="true">
      <div className="max-h-[92vh] w-full max-w-3xl overflow-y-auto rounded-lg bg-white shadow-2xl dark:bg-gray-950">
        <div className="sticky top-0 z-10 flex items-center justify-between border-b border-gray-100 bg-white px-4 py-3 dark:border-gray-800 dark:bg-gray-950 sm:px-6">
          <div>
            <h2 className="text-base font-bold text-gray-900 dark:text-gray-100 sm:text-lg">{copy.title}</h2>
            <p className="mt-0.5 text-xs font-medium text-[#ff4d4f]">{copy.review}</p>
          </div>
          <button
            type="button"
            onClick={onClose}
            disabled={busy}
            aria-label={copy.close}
            className="flex h-9 w-9 items-center justify-center rounded-lg border border-gray-200 text-xl leading-none text-gray-500 transition-colors hover:bg-gray-50 hover:text-gray-900 disabled:opacity-50 dark:border-gray-800 dark:text-gray-400 dark:hover:bg-gray-900 dark:hover:text-gray-100"
          >
            x
          </button>
        </div>

        <form onSubmit={submit} className="space-y-5 px-4 py-5 sm:px-6">
          {!submissionType && (
            <div className="grid grid-cols-2 gap-2 rounded-lg bg-gray-100 p-1 dark:bg-gray-900">
              {(["ebook", "video"] as SubmissionType[]).map((type) => (
                <button
                  key={type}
                  type="button"
                  onClick={() => set("type", type)}
                  className={`rounded-md px-3 py-2 text-sm font-bold transition-colors ${
                    form.type === type
                      ? "bg-[#ff4d4f] text-white shadow-sm"
                      : "text-gray-600 hover:bg-white dark:text-gray-300 dark:hover:bg-gray-800"
                  }`}
                >
                  {type === "ebook" ? copy.ebook : copy.video}
                </button>
              ))}
            </div>
          )}

          <div className="grid gap-4 sm:grid-cols-2">
            <label className="block">
              <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.name}</span>
              <input
                value={form.authorName}
                onChange={(event) => set("authorName", event.target.value)}
                className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
                placeholder="Nomad"
              />
            </label>
            <label className="block">
              <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.email}</span>
              <input
                type="email"
                value={form.authorEmail}
                onChange={(event) => set("authorEmail", event.target.value)}
                className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
                placeholder="you@example.com"
                required
              />
            </label>
          </div>

          <label className="block">
            <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.contentTitle}</span>
            <input
              value={form.title}
              onChange={(event) => set("title", event.target.value)}
              className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
              required
            />
          </label>

          <label className="block">
            <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.subtitle}</span>
            <input
              value={form.subtitle}
              onChange={(event) => set("subtitle", event.target.value)}
              className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
            />
          </label>

          <label className="block">
            <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.description}</span>
            <textarea
              value={form.description}
              onChange={(event) => set("description", event.target.value)}
              className="min-h-28 w-full resize-y rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm leading-6 text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
              required
            />
          </label>

          <div className="grid gap-4 sm:grid-cols-2">
            <div>
              <div className="mb-1.5 flex items-center justify-between gap-3">
                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.cover}</span>
                <label className="cursor-pointer rounded-lg bg-gray-900 px-3 py-1.5 text-xs font-bold text-white transition-colors hover:bg-[#ff4d4f] dark:bg-gray-100 dark:text-gray-900">
                  {uploading === "coverImage" ? copy.uploading : copy.uploadCover}
                  <input
                    type="file"
                    accept="image/jpeg,image/png,image/webp"
                    className="hidden"
                    disabled={busy}
                    onChange={(event) => void uploadFile(event, "coverImage")}
                  />
                </label>
              </div>
              <input
                value={form.coverImage}
                onChange={(event) => set("coverImage", event.target.value)}
                className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
                placeholder={copy.coverUrl}
                required
              />
              {form.coverImage && (
                <img src={mediaUrl(form.coverImage)} alt="" className="mt-3 h-32 w-full rounded-lg object-cover ring-1 ring-gray-100 dark:ring-gray-800" />
              )}
            </div>

            <div>
              <div className="mb-1.5 flex items-center justify-between gap-3">
                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.file}</span>
                <label className="cursor-pointer rounded-lg bg-gray-900 px-3 py-1.5 text-xs font-bold text-white transition-colors hover:bg-[#ff4d4f] dark:bg-gray-100 dark:text-gray-900">
                  {uploading === "mediaUrl" ? copy.uploading : copy.uploadFile}
                  <input
                    type="file"
                    accept={contentAccept}
                    className="hidden"
                    disabled={busy}
                    onChange={(event) => void uploadFile(event, "mediaUrl")}
                  />
                </label>
              </div>
              <input
                value={form.mediaUrl}
                onChange={(event) => set("mediaUrl", event.target.value)}
                className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
                placeholder={copy.fileUrl}
                required
              />
              <p className="mt-2 text-xs text-gray-400 dark:text-gray-500">Max {Math.round(mediaMaxSize / MB)}MB</p>
            </div>
          </div>

          <label className="block">
            <span className="mb-1.5 block text-sm font-semibold text-gray-700 dark:text-gray-300">{copy.chapters}</span>
            <textarea
              value={form.chaptersText}
              onChange={(event) => set("chaptersText", event.target.value)}
              className="min-h-20 w-full resize-y rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm leading-6 text-gray-900 outline-none transition-colors focus:border-[#ff4d4f] dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100"
              placeholder={copy.chaptersHint}
            />
          </label>

          {error && <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm font-medium text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200">{error}</div>}
          {message && <div className="rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm font-medium text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200">{message}</div>}

          <div className="flex flex-col-reverse gap-3 border-t border-gray-100 pt-4 dark:border-gray-800 sm:flex-row sm:justify-end">
            <button
              type="button"
              onClick={onClose}
              disabled={busy}
              className="rounded-lg border border-gray-200 px-5 py-2.5 text-sm font-bold text-gray-700 transition-colors hover:bg-gray-50 disabled:opacity-50 dark:border-gray-800 dark:text-gray-300 dark:hover:bg-gray-900"
            >
              {copy.close}
            </button>
            <button
              type="submit"
              disabled={busy}
              className="rounded-lg bg-[#ff4d4f] px-5 py-2.5 text-sm font-bold text-white transition-colors hover:bg-[#ff7a45] disabled:cursor-not-allowed disabled:opacity-60"
            >
              {submitting ? copy.submitting : copy.submit}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
