"use client";

import { useState, useCallback } from "react";
import { likeService, LIKE_STATUS, LikeStatus } from "@/services/likeService";
import { useRequireAuth } from "@/hooks/useRequireAuth";

interface UseLikeDislikeOptions {
  contentId: string | number;
  contentType: number;
  initialLikes: number;
  initialDislikes: number;
  /** 0=none, 1=liked, 2=disliked */
  initialReaction: number;
  episodeId?: number;
}

interface UseLikeDislikeResult {
  liked: boolean;
  disliked: boolean;
  totalLikes: number;
  totalDislikes: number;
  loading: boolean;
  handleLike: () => void;
  handleDislike: () => void;
}

/**
 * Reusable like/dislike hook with optimistic UI updates and error rollback.
 *
 * Reaction matrix:
 *   neutral  → like    : status=1, likes+1
 *   neutral  → dislike : status=2, dislikes+1
 *   liked    → like    : status=0, likes-1   (toggle off)
 *   liked    → dislike : status=2, likes-1, dislikes+1
 *   disliked → dislike : status=0, dislikes-1 (toggle off)
 *   disliked → like    : status=1, dislikes-1, likes+1
 */
export function useLikeDislike({
  contentId,
  contentType,
  initialLikes,
  initialDislikes,
  initialReaction,
  episodeId = 0,
}: UseLikeDislikeOptions): UseLikeDislikeResult {
  const [liked,         setLiked]         = useState(initialReaction === 1);
  const [disliked,      setDisliked]       = useState(initialReaction === 2);
  const [totalLikes,    setTotalLikes]     = useState(initialLikes);
  const [totalDislikes, setTotalDislikes]  = useState(initialDislikes);
  const [loading,       setLoading]        = useState(false);
  const requireAuth = useRequireAuth();

  const react = useCallback(async (status: LikeStatus) => {
    if (loading) return;

    // Snapshot for rollback
    const prevLiked        = liked;
    const prevDisliked     = disliked;
    const prevTotalLikes   = totalLikes;
    const prevTotalDislikes = totalDislikes;

    // Optimistic update
    if (status === LIKE_STATUS.LIKE) {
      setLiked(true);
      setDisliked(false);
      setTotalLikes((n) => n + 1);
      if (prevDisliked) setTotalDislikes((n) => Math.max(0, n - 1));
    } else if (status === LIKE_STATUS.DISLIKE) {
      setDisliked(true);
      setLiked(false);
      setTotalDislikes((n) => n + 1);
      if (prevLiked) setTotalLikes((n) => Math.max(0, n - 1));
    } else {
      // remove
      setLiked(false);
      setDisliked(false);
      if (prevLiked)    setTotalLikes((n) => Math.max(0, n - 1));
      if (prevDisliked) setTotalDislikes((n) => Math.max(0, n - 1));
    }

    setLoading(true);
    try {
      const res = await likeService.react(contentId, contentType, status, episodeId);
      if (res.status !== 200) throw new Error(res.message);
    } catch {
      // Rollback
      setLiked(prevLiked);
      setDisliked(prevDisliked);
      setTotalLikes(prevTotalLikes);
      setTotalDislikes(prevTotalDislikes);
    } finally {
      setLoading(false);
    }
  }, [loading, liked, disliked, totalLikes, totalDislikes, contentId, contentType, episodeId]);

  const handleLike = useCallback(() =>
    requireAuth(() => react(liked ? LIKE_STATUS.REMOVE : LIKE_STATUS.LIKE)),
    [liked, react, requireAuth]);

  const handleDislike = useCallback(() =>
    requireAuth(() => react(disliked ? LIKE_STATUS.REMOVE : LIKE_STATUS.DISLIKE)),
    [disliked, react, requireAuth]);

  return { liked, disliked, totalLikes, totalDislikes, loading, handleLike, handleDislike };
}
