"use client";

import { getNotifications, markAllAsRead, markAsRead } from "@/libs/axios/modules/notification";
import type NotificationModel from "@/models/notification";
import { motion } from "framer-motion";
import { useEffect, useState } from "react";

const LIMIT = 10;

const formatDate = (dateStr: string) =>
  new Date(dateStr).toLocaleString("id-ID", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  });

function SkeletonList() {
  return (
    <div className="divide-y divide-gray-50">
      {Array.from({ length: 5 }).map((_, i) => (
        <div key={i} className="flex items-start gap-3 px-4 py-3 animate-pulse">
          <div className="mt-1.5 w-2 h-2 rounded-full bg-gray-200 shrink-0" />
          <div className="flex-1 space-y-2">
            <div className="h-3.5 bg-gray-200 rounded w-3/4" />
            <div className="h-3 bg-gray-200 rounded w-full" />
            <div className="h-3 bg-gray-200 rounded w-1/3" />
          </div>
        </div>
      ))}
    </div>
  );
}

type Props = {
  token: string;
  onUnreadChange: (count: number) => void;
};

export default function NotificationPanel({ token, onUnreadChange }: Props) {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState<NotificationModel[]>([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(false);
  const [fetchingMore, setFetchingMore] = useState(false);

  const fetchData = async (nextPage = 1) => {
    if (!token) return;
    try {
      nextPage === 1 ? setLoading(true) : setFetchingMore(true);
      const { data: res } = await getNotifications(token, { page: nextPage, limit: LIMIT });
      const newItems: NotificationModel[] = res.data?.data ?? [];
      const total: number = res.data?.total ?? 0;
      setData(prev =>
        nextPage === 1
          ? newItems
          : [...prev, ...newItems.filter(n => !prev.some(p => p.id === n.id))]
      );
      setPage(nextPage);
      setHasMore(nextPage * LIMIT < total);
    } catch {}
    finally {
      setLoading(false);
      setFetchingMore(false);
    }
  };

  useEffect(() => { fetchData(1); }, []);

  const handleItemClick = (item: NotificationModel) => {
    if (item.read_at) return;
    const updated = data.map(n =>
      n.id === item.id ? { ...n, read_at: new Date().toISOString() } : n
    );
    setData(updated);
    onUnreadChange(updated.filter(n => !n.read_at).length);
    markAsRead(token, item.id).catch(() => {});
  };

  const handleMarkAll = async () => {
    try {
      await markAllAsRead(token);
      setData(prev => prev.map(n => ({ ...n, read_at: n.read_at ?? new Date().toISOString() })));
      onUnreadChange(0);
    } catch {}
  };

  return (
    <motion.div
      initial={{ opacity: 0, y: -8 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -8 }}
      transition={{ duration: 0.18, ease: "easeOut" }}
      className="absolute right-0 top-full mt-3 w-80 bg-white rounded-2xl border border-gray-100 shadow-xl z-50 overflow-hidden"
    >
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-3 border-b border-gray-100">
        <h3 className="font-semibold text-sm text-gray-900">Notifikasi</h3>
        <button
          onClick={handleMarkAll}
          className="text-xs text-primary-500 hover:underline"
        >
          Tandai semua dibaca
        </button>
      </div>

      {/* List */}
      <div className="max-h-96 overflow-y-auto divide-y divide-gray-50">
        {loading ? (
          <SkeletonList />
        ) : data.length === 0 ? (
          <p className="text-center text-sm text-gray-400 py-12">
            Belum ada notifikasi
          </p>
        ) : (
          <>
            {data.map(item => {
              const isUnread = !item.read_at;
              return (
                <button
                  key={item.id}
                  onClick={() => handleItemClick(item)}
                  className={`w-full flex items-start gap-3 px-4 py-3 text-left hover:bg-gray-50 transition-colors ${isUnread ? "bg-primary-50" : ""}`}
                >
                  <div
                    className={`mt-1.5 w-2 h-2 rounded-full shrink-0 ${isUnread ? "bg-primary-500" : "bg-transparent"}`}
                  />
                  <div className="flex-1 min-w-0">
                    <p className={`text-sm text-gray-900 line-clamp-2 ${isUnread ? "font-semibold" : "font-normal"}`}>
                      {item.title}
                    </p>
                    {item.subtitle && (
                      <p className="text-xs text-gray-500 mt-0.5 line-clamp-2">
                        {item.subtitle}
                      </p>
                    )}
                    <p className="text-xs text-gray-400 mt-1">
                      {formatDate(item.created_at)}
                    </p>
                  </div>
                </button>
              );
            })}

            {hasMore && (
              <button
                onClick={() => fetchData(page + 1)}
                disabled={fetchingMore}
                className="w-full py-3 text-sm text-primary-500 hover:bg-gray-50 transition-colors disabled:opacity-50"
              >
                {fetchingMore ? "Memuat..." : "Muat lebih banyak"}
              </button>
            )}
          </>
        )}
      </div>
    </motion.div>
  );
}
