"use client";

import { useTranslation } from "@/hooks/useTranslation";
import { storeLikePost } from "@/libs/axios/modules/post";
import { ChapterModel, PostModel } from "@/models";
import { withSlug } from "@/utils/slug";
import {
  AnimatePresence,
  motion,
  useScroll,
  useTransform,
} from "framer-motion";
import {
  ArrowRight,
  BookOpen,
  Bookmark,
  ChevronRight,
  ExternalLink,
  Lock,
  Share2,
  Star,
} from "lucide-react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useCallback, useRef, useState } from "react";
import { toast } from "react-toastify";

function getNumber(n?: number) {
  if (!n) return "0";
  if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + "M";
  if (n >= 1_000) return (n / 1_000).toFixed(1) + "K";
  return n.toString();
}

function starRating(sum: number, count: number) {
  if (!count) return 0;
  return Math.min(5, Math.round(sum / count));
}

function redirectToApp() {
  window.open(
    "https://play.google.com/store/apps/details?id=com.kutubuku",
    "_blank",
  );
}

function SectionTitle({ children }: { children: React.ReactNode }) {
  return (
    <h2 className="flex items-center gap-2 text-base font-bold text-slate-800">
      <span className="w-1 h-5 bg-primary-500 rounded-full shrink-0" />
      {children}
    </h2>
  );
}

function AuthorCard({ novel }: { novel: PostModel }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true }}
      transition={{ duration: 0.5 }}
      className="flex items-center justify-between gap-4 bg-white rounded-2xl border border-slate-100 p-4 shadow-sm"
    >
      <div className="flex items-center gap-3">
        <img
          src={novel.author?.avatar || "/assets/DefaultProfile.png"}
          alt={novel.author?.name}
          className="w-12 h-12 rounded-full object-cover ring-2 ring-slate-100"
        />

        <div>
          <p className="font-semibold text-slate-800 text-sm">
            {novel.author?.name}
          </p>

          <p className="text-xs text-slate-400 mt-0.5!">
            <strong className="text-slate-600">
              {novel.author?.total_followers ?? 0}
            </strong>{" "}
            Pengikut ·{" "}
            <strong className="text-slate-600">
              {novel.author?.total_posts ?? 0}
            </strong>{" "}
            Novel
          </p>
        </div>
      </div>

      <button className="bg-primary-500 hover:bg-primary-600 text-white text-xs font-semibold px-4 py-2 rounded-full transition-colors cursor-pointer shrink-0">
        Ikuti
      </button>
    </motion.div>
  );
}

function HeroSection({
  novel,
  token,
}: {
  novel: PostModel;
  token?: string;
}) {
  const { t, language } = useTranslation();
  const router = useRouter();

  const ref = useRef<HTMLDivElement>(null);

  const { scrollY } = useScroll();

  const bgY = useTransform(scrollY, [0, 500], [0, 120]);

  const rating = starRating(
    novel.total_sum_reviews ?? 0,
    novel.total_reviews ?? 0,
  );

  const [isBookmarked, setIsBookmarked] = useState(
    novel.is_bookmark ?? false,
  );

  const [bookmarkLoading, setBookmarkLoading] = useState(false);

  const handleRead = () => {
    if (!novel.last_view_chapter) return;

    if (novel.last_view_chapter.is_paid) {
      redirectToApp();
    } else {
      router.push(
        `/${language}/novel/${withSlug(novel.id, novel.slug)}/read/${withSlug(novel.last_view_chapter.id, novel.last_view_chapter.slug)}`,
      );
    }
  };

  const handleShare = async () => {
    const url = `${window.location.origin}/${language}/novel/${withSlug(novel.id, novel.slug)}`;

    if (navigator.share) {
      await navigator.share({
        title: novel.title,
        url,
      });
    } else {
      await navigator.clipboard.writeText(url);
      toast.success("Link disalin!");
    }
  };

  const handleBookmark = useCallback(async () => {
    if (!token) {
      toast.error(t("you need to login first"));
      return;
    }

    setBookmarkLoading(true);

    try {
      const { data: res } = await storeLikePost(token, {
        id: novel.id,
      });

      if (res?.data) {
        setIsBookmarked(res.data.is_bookmark);
      }
    } catch (err: any) {
      toast.error(err?.data?.message ?? "Gagal");
    } finally {
      setBookmarkLoading(false);
    }
  }, [token, novel.id, t]);

  return (
    <div
      ref={ref}
      className="relative overflow-hidden"
      style={{ minHeight: 700 }}
    >
      <motion.div
        style={{ y: bgY }}
        className="absolute inset-0 scale-110"
      >
        <img
          src={novel.image ?? "/default-cover.jpg"}
          alt=""
          className="w-full h-full object-cover blur-sm"
        />

        <div className="absolute inset-0 bg-linear-to-b from-black/75 via-black/55 to-[#f5f5f0]" />

        <div
          className="absolute inset-0 opacity-20 mix-blend-overlay"
          style={{
            backgroundImage:
              "url(\"data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='1'/%3E%3C/svg%3E\")",
          }}
        />
      </motion.div>

      <div className="relative z-10 w-full min-h-screen flex flex-col items-center px-4 pt-30 text-center gap-8 lg:gap-4">
        <motion.div
          initial={{ opacity: 0, y: 40, scale: 0.92 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          transition={{
            duration: 0.7,
            ease: [0.22, 1, 0.36, 1],
          }}
          className="relative"
        >
          <div
            className="relative w-44 rounded-2xl overflow-hidden shadow-[0_32px_64px_rgba(0,0,0,0.6)] ring-1 ring-white/10"
            style={{ aspectRatio: "2/3" }}
          >
            <Image
              src={novel.image ?? "/default-cover.jpg"}
              alt={novel.title}
              fill
              priority
              sizes="176px"
              className="object-cover"
            />
          </div>

          {novel.preference?.age?.title && (
            <span className="absolute top-2 right-2 bg-black/70 text-white text-[10px] font-bold px-2 py-0.5 rounded-full backdrop-blur-sm">
              {novel.preference.age.title}
            </span>
          )}
        </motion.div>

        <div className="gap-1">
        <motion.h1
          initial={{ opacity: 0, y: 24 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{
            delay: 0.2,
            duration: 0.6,
          }}
          className="text-3xl font-bold text-white leading-tight max-w-xl tracking-tight"
        >
          {novel.title}
        </motion.h1>

        <motion.p
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{
            delay: 0.35,
          }}
          className="mt-1! text-sm text-white/70 font-medium"
        >
          oleh{" "}
          <span className="text-white font-semibold">
            {novel.author?.name ?? "Unknown"}
          </span>{" "}
          · {novel.total_chapters ?? 0} Bab
        </motion.p>

        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{
            delay: 0.45,
          }}
          className="mt-1! justify-center flex items-center gap-1.5"
        >
          {Array.from({ length: 5 }).map((_, i) => (
            <Star
              key={i}
              className={`w-4 h-4 ${
                i < rating
                  ? "fill-yellow-400 text-yellow-400"
                  : "text-white/30"
              }`}
            />
          ))}

          <span className="text-white/60 text-xs ml-1!">
            {rating.toFixed(1)} · {novel.total_reviews ?? 0} ulasan
          </span>
        </motion.div>
        </div>

        <motion.div
          initial={{ opacity: 0, y: 16 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{
            delay: 0.5,
          }}
          className=" grid grid-cols-3 divide-x divide-white/10 bg-white/10 backdrop-blur-md rounded-2xl overflow-hidden border border-white/10 w-full max-w-sm"
        >
          <div className="py-3 px-2 text-center">
            <p className="text-base font-bold text-white leading-none">
              {getNumber(novel.total_viewers)}
            </p>

            <p className="text-[10px] text-white/50 mt-0.5! uppercase tracking-widest">
              Tayangan
            </p>
          </div>

          <div className="py-3 px-2 text-center">
            <p className="text-base font-bold text-white leading-none">
              {novel.is_finish ? "Selesai" : "Berlanjut"}
            </p>

            <p className="text-[10px] text-white/50 mt-0.5! uppercase tracking-widest">
              Status
            </p>
          </div>

          <a
            href={`/${language}/novel/${withSlug(novel.id, novel.slug)}/reviews`}
            className="py-3 px-2 text-center"
          >
            <p className="text-base font-bold text-white leading-none flex items-center justify-center gap-1">
              {getNumber(novel.total_reviews)}

              <ArrowRight className="w-3.5 h-3.5" />
            </p>

            <p className="text-[10px] text-white/50 mt-0.5! uppercase tracking-widest">
              Ulasan
            </p>
          </a>
        </motion.div>

        {novel.tags && novel.tags.length > 0 && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{
              delay: 0.6,
            }}
            className="flex flex-wrap justify-center gap-2 max-w-xl capitalize"
          >
            {novel.genre?.title && (
              <span className="bg-primary-500/90 text-white text-xs font-semibold px-3 py-1.5 rounded-full backdrop-blur-sm">
                {novel.genre.title}
              </span>
            )}

            {novel.tags.slice(0, 5).map((tag) => (
              <span
                key={tag.title}
                className="bg-white/10 text-white/80 text-xs px-3 py-1.5 rounded-full border border-white/10 backdrop-blur-sm"
              >
                {tag.title}
              </span>
            ))}
          </motion.div>
        )}

        <AnimatePresence>
          <motion.div
            initial={{ y: 80, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: 80, opacity: 0 }}
            transition={{
              delay: 0.7,
              duration: 0.4,
              ease: [0.22, 1, 0.36, 1],
            }}
            className="relative flex justify-center px-4 mb-4"
          >
            <div className="flex items-center gap-3 bg-white/90 backdrop-blur-md px-4 py-3 rounded-2xl shadow-[0_8px_32px_rgba(0,0,0,0.15)] border border-slate-100 w-full max-w-md">
              <button
                onClick={handleShare}
                className="w-11 h-11 rounded-xl border border-slate-200 flex items-center justify-center hover:bg-slate-50 transition-colors cursor-pointer shrink-0"
              >
                <Share2 className="w-4 h-4 text-slate-600" />
              </button>

              <button
                onClick={handleBookmark}
                disabled={bookmarkLoading}
                className={`w-11 h-11 rounded-xl border flex items-center justify-center transition-all cursor-pointer shrink-0
                ${
                  isBookmarked
                    ? "bg-primary-500 border-primary-500"
                    : "border-slate-200 hover:bg-slate-50"
                }`}
              >
                <Bookmark
                  className={`w-4 h-4 ${
                    isBookmarked
                      ? "fill-white text-white"
                      : "text-slate-600"
                  }`}
                />
              </button>

              <button
                onClick={handleRead}
                className=" min-w-60 flex-1 flex items-center justify-center gap-2 bg-primary-500 hover:bg-primary-600 active:scale-95 text-white py-3 rounded-xl text-sm font-bold transition-all cursor-pointer"
              >
                <BookOpen className="w-4 h-4" />

                {novel.last_view_chapter
                  ? `Lanjut Bab ${novel.last_view_chapter.order}`
                  : t("start reading")}
              </button>
            </div>
          </motion.div>
        </AnimatePresence>
      </div>
    </div>
  );
}

function OverviewTab({ novel }: { novel: PostModel }) {
  const [expanded, setExpanded] = useState(false);

  const desc = novel.description ?? "";

  const isLong = desc.length > 280;

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      className="flex flex-col gap-8 bg-white p-4 md:p-10 rounded-2xl shadow"
    >
      <section>
        <SectionTitle>Blurb</SectionTitle>

        <div className="relative mt-3!">
          <p
            className={`text-sm text-slate-600 leading-relaxed ${
              !expanded && isLong ? "line-clamp-5" : ""
            }`}
          >
            {desc || "Belum ada blurb."}
          </p>

          {isLong && (
            <button
              onClick={() => setExpanded((v) => !v)}
              className="mt-2! text-xs text-primary-500 font-semibold cursor-pointer hover:underline"
            >
              {expanded
                ? "Tampilkan lebih sedikit"
                : "Baca selengkapnya"}
            </button>
          )}
        </div>
      </section>

      {novel.last_view_chapter && (
        <section>
          <SectionTitle>
            Bab {novel.last_view_chapter.order} —{" "}
            {novel.last_view_chapter.title}
          </SectionTitle>

          <div
            className="mt-3! text-sm text-slate-500 leading-relaxed line-clamp-6 prose prose-sm max-w-none prose-p:text-slate-500"
            dangerouslySetInnerHTML={{
              __html: novel.last_view_chapter.description ?? "",
            }}
          />
        </section>
      )}

      <section>
        <SectionTitle>Penulis</SectionTitle>

        <div className="mt-3!">
          <AuthorCard novel={novel} />
        </div>
      </section>
    </motion.div>
  );
}

function CatalogTab({
  chapters,
  novel,
}: {
  chapters: ChapterModel[];
  novel: PostModel;
}) {
  const router = useRouter();
  const { language } = useTranslation();

  const [showAll, setShowAll] = useState(false);

  const displayed = showAll ? chapters : chapters.slice(0, 10);

  const handleChapterClick = (chapter: ChapterModel) => {
    if (chapter.is_paid) {
      redirectToApp();
    } else {
      router.push(`/${language}/novel/${withSlug(novel.id, novel.slug)}/read/${withSlug(chapter.id, chapter.slug)}`);
    }
  };

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      className="flex flex-col gap-1 bg-white p-4 md:p-10 rounded-2xl shadow"
    >
      {displayed.map((chapter, i) => (
        <motion.div
          key={chapter.id}
          initial={{ opacity: 0, x: -12 }}
          animate={{ opacity: 1, x: 0 }}
          transition={{
            delay: i * 0.03,
            duration: 0.35,
          }}
        >
          <button
            onClick={() => handleChapterClick(chapter)}
            className={`w-full flex items-center gap-4 px-4 py-4 rounded-xl transition-colors text-left cursor-pointer
            ${
              chapter.is_paid
                ? "hover:bg-slate-50 opacity-75"
                : "hover:bg-primary-50"
            }`}
          >
            <div
              className={`w-9 h-9 rounded-full flex items-center justify-center shrink-0 text-sm font-bold
              ${
                chapter.is_paid
                  ? "bg-slate-100 text-slate-400"
                  : "bg-primary-50 text-primary-600"
              }`}
            >
              {chapter.is_paid ? (
                <Lock className="w-3.5 h-3.5" />
              ) : (
                chapter.order
              )}
            </div>

            <div className="flex-1 min-w-0">
              <p
                className={`text-sm font-semibold truncate ${
                  chapter.is_paid
                    ? "text-slate-400"
                    : "text-slate-800"
                }`}
              >
                {chapter.title}
              </p>

              <p className="text-xs text-slate-400 mt-0.5!">
                {chapter.total_words ?? 0} kata ·{" "}
                {chapter.published_at}
              </p>
            </div>

            {chapter.is_paid ? (
              <div className="flex items-center gap-1 shrink-0">
                <ExternalLink className="w-3.5 h-3.5 text-slate-400" />

                <span className="text-xs text-slate-400">
                  App
                </span>
              </div>
            ) : (
              <ChevronRight className="w-4 h-4 text-primary-400 shrink-0" />
            )}
          </button>
        </motion.div>
      ))}

      {!showAll && chapters.length > 10 && (
        <button
          onClick={() => setShowAll(true)}
          className="mt-4! w-full py-3 rounded-full border border-primary-500 text-primary-500 text-sm font-semibold hover:bg-primary-50 transition-colors cursor-pointer"
        >
          Lihat semua {chapters.length} bab
        </button>
      )}
    </motion.div>
  );
}

interface Props {
  novel: PostModel;
  chapters: ChapterModel[];
  token?: string;
}

export default function NovelDetailPage({
  novel,
  chapters,
  token,
}: Props) {
  const [activeTab, setActiveTab] = useState<
    "overview" | "catalog"
  >("overview");

  return (
    <div className="w-full min-h-screen bg-[#f5f5f0]">
      <HeroSection novel={novel} token={token} />

      <div className="relative z-10 pb-10 mx-auto px-4 sm:px-6 lg:px-32 xl:px-48">
        <div className="w-full flex justify-center py-2">
          <motion.div
            initial={{ opacity: 0, y: 12 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.65 }}
            className="flex w-full  gap-1 bg-white rounded-2xl p-1 shadow-sm border border-slate-100 "
          >
            {(["overview", "catalog"] as const).map((tab) => (
              <button
                key={tab}
                onClick={() => setActiveTab(tab)}
                className={`flex-1 py-2.5 rounded-xl text-sm font-semibold transition-all cursor-pointer capitalize
                ${
                  activeTab === tab
                    ? "bg-primary-500 text-white shadow-sm"
                    : "text-slate-500 hover:text-slate-700"
                }`}
              >
                {tab === "overview"
                  ? "Blurb"
                  : "Daftar Bab"}
              </button>
            ))}
          </motion.div>
        </div>

        <AnimatePresence mode="wait">
          {activeTab === "overview" ? (
            <OverviewTab
              key="overview"
              novel={novel}
            />
          ) : (
            <CatalogTab
              key="catalog"
              chapters={chapters}
              novel={novel}
            />
          )}
        </AnimatePresence>
      </div>
    </div>
  );
}