/* eslint-disable @next/next/no-img-element */

"use client";

import useAxios from "@/hooks/useAxios";
import { optimizeImageToWebP, optimizeVideoToMp4 } from "@/lib/media";
import { createStoryBase64, StoryTextOverlay } from "@/api/fetchStories";
import StoryEditor from "@/components/stories/StoryEditor";
import TagUsersPicker, { TaggedUser } from "@/components/posts/TagUsersPicker";
import BoldIcon from "@/components/ui/BoldIcon";
import Cookies from "js-cookie";
import { useRouter, useSearchParams } from "next/navigation";
import React, { useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";

type CreateMode = "image" | "video" | "story";

const MODE_LABELS: Record<CreateMode, string> = {
  image: "عکس",
  video: "ویدئو",
  story: "استوری",
};

function fileToBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = reject;
  });
}

export default function NewPostPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { request, loading } = useAxios();

  const initialMode = (searchParams.get("type") as CreateMode) || "image";
  const [mode, setMode] = useState<CreateMode>(
    ["image", "video", "story"].includes(initialMode) ? initialMode : "image"
  );
  const [file, setFile] = useState<File | null>(null);
  const [preview, setPreview] = useState<string>("");
  const [extraImages, setExtraImages] = useState<(File | null)[]>([null]);
  const [extraPreviews, setExtraPreviews] = useState<string[]>([""]);
  const [description, setDescription] = useState("");
  const [taggedUsers, setTaggedUsers] = useState<TaggedUser[]>([]);
  const [storyOverlays, setStoryOverlays] = useState<StoryTextOverlay[]>([]);

  useEffect(() => {
    const t = searchParams.get("type") as CreateMode;
    if (t && ["image", "video", "story"].includes(t)) setMode(t);
  }, [searchParams]);

  const resetMedia = () => {
    if (preview) URL.revokeObjectURL(preview);
    extraPreviews.forEach((p) => p && URL.revokeObjectURL(p));
    setFile(null);
    setPreview("");
    setExtraImages([null]);
    setExtraPreviews([""]);
    setStoryOverlays([]);
  };

  const switchMode = (next: CreateMode) => {
    resetMedia();
    setMode(next);
  };

  const acceptAttr = useMemo(() => {
    if (mode === "video" || mode === "story") return "video/*,image/*";
    return "image/*";
  }, [mode]);

  const onPickMain = (e: React.ChangeEvent<HTMLInputElement>) => {
    const picked = e.target.files?.[0];
    if (!picked) return;

    if (mode === "video" && !picked.type.startsWith("video/")) {
      toast.error("فقط ویدئو مجاز است");
      return;
    }
    if (mode === "image" && !picked.type.startsWith("image/")) {
      toast.error("فقط تصویر مجاز است");
      return;
    }

    if (preview) URL.revokeObjectURL(preview);
    setFile(picked);
    setPreview(URL.createObjectURL(picked));
  };

  const onPickExtra = (index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
    const picked = e.target.files?.[0];
    if (!picked || !picked.type.startsWith("image/")) {
      toast.error("فقط تصویر مجاز است");
      return;
    }
    const files = [...extraImages];
    const previews = [...extraPreviews];
    files[index] = picked;
    previews[index] = URL.createObjectURL(picked);
    setExtraImages(files);
    setExtraPreviews(previews);
    if (files.filter(Boolean).length < 10 && index === files.length - 1) {
      setExtraImages((prev) => [...prev, null]);
      setExtraPreviews((prev) => [...prev, ""]);
    }
  };

  const publish = async () => {
    const token = Cookies.get("token");
    if (!token) {
      toast.error("لطفاً وارد حساب کاربری شوید");
      return;
    }

    if (mode === "story") {
      if (!file) {
        toast.error("انتخاب عکس یا ویدئو برای استوری الزامی است");
        return;
      }
      try {
        toast.loading("در حال انتشار استوری…", { id: "story-upload" });
        let optimized: File;
        if (file.type.startsWith("video/")) {
          // اگر تبدیل ویدیو (ffmpeg) در دسترس نبود، فایل اصلی ارسال می‌شود
          try {
            optimized = await optimizeVideoToMp4(file);
          } catch {
            optimized = file;
          }
        } else {
          try {
            optimized = await optimizeImageToWebP(file);
          } catch {
            optimized = file;
          }
        }
        await createStoryBase64(
          {
            name: optimized.name,
            type: optimized.type,
            data: await fileToBase64(optimized),
          },
          token,
          storyOverlays
        );
        toast.success("استوری منتشر شد", { id: "story-upload" });
        router.push("/");
      } catch (err) {
        toast.error(err instanceof Error ? err.message : "خطا در انتشار استوری", {
          id: "story-upload",
        });
      }
      return;
    }

    const imageFiles =
      mode === "image"
        ? [...(file ? [file] : []), ...extraImages.filter(Boolean)] as File[]
        : file
          ? [file]
          : [];

    if (!imageFiles.length) {
      toast.error("انتخاب مدیا الزامی است");
      return;
    }
    if (!description.trim()) {
      toast.error("نوشتن کپشن الزامی است");
      return;
    }

    try {
      toast.loading("در حال آپلود…", { id: "post-upload" });
      const optimizedFiles = await Promise.all(
        imageFiles.map(async (f) =>
          f.type.startsWith("video/")
            ? optimizeVideoToMp4(f)
            : optimizeImageToWebP(f)
        )
      );
      const filesBase64 = await Promise.all(
        optimizedFiles.map(async (f) => ({
          name: f.name,
          type: f.type,
          data: await fileToBase64(f),
        }))
      );
      const tagLine = taggedUsers.map((u) => `@${u.user_name}`).join(" ");
      const caption = [description, tagLine].filter(Boolean).join("\n");

      await request("POST", "/posts/create-base64", {
        files: filesBase64,
        caption,
        tagged_user_ids: taggedUsers.map((u) => u._id),
      });
      toast.success("پست منتشر شد", { id: "post-upload" });
      router.push("/");
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "خطا در آپلود", {
        id: "post-upload",
      });
    }
  };

  const isStory = mode === "story";

  return (
    <div className="mx-auto flex min-h-[calc(100dvh-8rem)] max-w-lg flex-col bg-background">
      {/* Header — Instagram style */}
      <header className="sticky top-0 z-10 flex items-center justify-between border-b border-neutral-200 px-4 py-3 dark:border-neutral-800">
        <button
          type="button"
          onClick={() => router.back()}
          className="flex h-9 w-9 items-center justify-center"
          aria-label="بازگشت"
        >
          <BoldIcon name="arrow-right-3" size={22} className="block dark:invert" />
        </button>
        <span className="text-base font-semibold">
          {isStory ? "استوری جدید" : "پست جدید"}
        </span>
        <button
          type="button"
          onClick={publish}
          disabled={loading}
          className="text-sm font-semibold text-[#0095f6] disabled:opacity-40"
        >
          {loading ? "…" : "اشتراک"}
        </button>
      </header>

      {/* Mode tabs */}
      <div className="flex border-b border-neutral-200 dark:border-neutral-800">
        {(["image", "video", "story"] as CreateMode[]).map((m) => (
          <button
            key={m}
            type="button"
            onClick={() => switchMode(m)}
            className={`flex-1 py-3 text-sm font-semibold transition ${
              mode === m
                ? "border-b-2 border-neutral-900 text-neutral-900 dark:border-white dark:text-white"
                : "text-neutral-400"
            }`}
          >
            {MODE_LABELS[m]}
          </button>
        ))}
      </div>

      {/* Story editor (media + draggable text) */}
      {isStory && preview && file ? (
        <div className="flex flex-col gap-3 p-4">
          <StoryEditor
            mediaUrl={preview}
            mediaType={file.type.startsWith("video/") ? "video" : "image"}
            overlays={storyOverlays}
            onChange={setStoryOverlays}
          />
          <label className="mx-auto rounded-lg bg-neutral-100 px-4 py-2 text-center text-xs text-neutral-600 dark:bg-neutral-800 dark:text-neutral-300">
            تغییر فایل
            <input
              type="file"
              accept={acceptAttr}
              className="hidden"
              onChange={onPickMain}
            />
          </label>
        </div>
      ) : (
      /* Media area */
      <div
        className={`relative flex flex-1 flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-950 ${
          isStory ? "aspect-[9/16] max-h-[55vh]" : "min-h-[280px]"
        }`}
      >
        {preview ? (
          <>
            {file?.type.startsWith("video/") ? (
              <video
                src={preview}
                className="max-h-[55vh] w-full object-contain"
                controls
                playsInline
              />
            ) : (
              <img
                src={preview}
                alt="preview"
                className={`w-full object-contain ${isStory ? "max-h-[55vh]" : "max-h-[360px]"}`}
              />
            )}
            <button
              type="button"
              onClick={resetMedia}
              className="absolute left-3 top-3 rounded-full bg-black/50 p-2"
            >
              <BoldIcon name="close-circle" size={20} tinted className="text-white" />
            </button>
          </>
        ) : (
          <label className="flex cursor-pointer flex-col items-center gap-3 p-8 text-neutral-500">
            <BoldIcon name="gallery-add" size={48} className="block opacity-60 dark:invert" />
            <span className="text-sm">
              {isStory
                ? "عکس یا ویدئو استوری را انتخاب کنید"
                : mode === "video"
                  ? "ویدئو را انتخاب کنید"
                  : "عکس را انتخاب کنید"}
            </span>
            <span className="rounded-lg bg-[#0095f6] px-4 py-2 text-sm font-semibold text-white">
              انتخاب از گالری
            </span>
            <input
              type="file"
              accept={acceptAttr}
              className="hidden"
              onChange={onPickMain}
            />
          </label>
        )}
        {preview && (
          <label className="absolute bottom-4 rounded-lg bg-black/60 px-4 py-2 text-xs text-white">
            تغییر فایل
            <input type="file" accept={acceptAttr} className="hidden" onChange={onPickMain} />
          </label>
        )}
      </div>
      )}

      {/* Extra images for photo post */}
      {mode === "image" && !isStory && (
        <div className="grid grid-cols-4 gap-2 border-t border-neutral-200 p-3 dark:border-neutral-800">
          {[...(file ? [preview] : []), ...extraPreviews.filter(Boolean)]
            .slice(0, 4)
            .map((p, i) => (
              <div key={i} className="relative aspect-square overflow-hidden rounded-md bg-neutral-200">
                {p && <img src={p} alt="" className="h-full w-full object-cover" />}
              </div>
            ))}
          {extraPreviews.map((p, index) =>
            !p ? (
              <label
                key={`slot-${index}`}
                className="flex aspect-square cursor-pointer items-center justify-center rounded-md border border-dashed border-neutral-300 dark:border-neutral-700"
              >
                <BoldIcon name="add" size={20} className="block dark:invert" />
                <input
                  type="file"
                  accept="image/*"
                  className="hidden"
                  onChange={onPickExtra(index)}
                />
              </label>
            ) : null
          )}
        </div>
      )}

      {/* Caption — not for story */}
      {!isStory && (
        <div className="space-y-3 border-t border-neutral-200 p-4 dark:border-neutral-800">
          <textarea
            placeholder="کپشن بنویسید…"
            value={description}
            onChange={(e) => {
              if (e.target.value.length <= 1000) setDescription(e.target.value);
            }}
            rows={3}
            className="w-full resize-none bg-transparent text-sm outline-none placeholder:text-neutral-400"
          />
          <div className="flex justify-between text-xs text-neutral-400">
            <span>{description.length}/1000</span>
          </div>
          <TagUsersPicker selected={taggedUsers} onChange={setTaggedUsers} max={50} />
        </div>
      )}

      {isStory && (
        <p className="px-4 pb-6 text-center text-xs text-neutral-500">
          استوری شما ۲۴ ساعت نمایش داده می‌شود و سپس به‌طور خودکار حذف می‌گردد.
        </p>
      )}
    </div>
  );
}
