"use client";

import React from "react";
import Button from "@/components/ui/button/Button";
import { ArrowDown } from "lucide-react";
import ArticleBody from "@/modules/newsModule/components/ArticleBody";
import { hasPortableTextContent } from "@/lib/tenantContent";

interface ModalTnCProps {
  isOpen: boolean;
  onClose: () => void;
  onAgree: () => void;
  onScroll: (e: React.UIEvent<HTMLDivElement>) => void;
  onContentReady?: (el: HTMLDivElement) => void;
  autoScrollDurationMs?: number;
  title?: string;
  body?: any;
}

export default function ModalTnC({
  isOpen,
  onClose,
  onAgree,
  onScroll,
  onContentReady,
  autoScrollDurationMs = 1200,
  title,
  body,
}: ModalTnCProps) {
  const scrollRef = React.useRef<HTMLDivElement>(null);
  const wasOpenRef = React.useRef(false);
  const [isAtBottom, setIsAtBottom] = React.useState(false);
  const hasBody = hasPortableTextContent(body);

  const handleInternalScroll = (e: React.UIEvent<HTMLDivElement>) => {
    onScroll?.(e);
    const target = e.currentTarget;
    const threshold = 8;
    const reachedBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - threshold;
    setIsAtBottom(reachedBottom);
  };

  React.useEffect(() => {
    const justOpened = isOpen && !wasOpenRef.current;
    wasOpenRef.current = isOpen;
    if (!isOpen) return;
    const container = scrollRef.current;
    if (!container) return;

    if (justOpened) {
      setIsAtBottom(false);
      container.scrollTop = 0;
    }

    const rafId = requestAnimationFrame(() => {
      onContentReady?.(container);
      const threshold = 8;
      const reachedBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - threshold;
      setIsAtBottom(reachedBottom);
    });

    return () => cancelAnimationFrame(rafId);
  }, [isOpen, body, title, onContentReady]);

  const animateScrollToBottom = React.useCallback(() => {
    const container = scrollRef.current;
    if (!container) return;

    const start = container.scrollTop;
    const end = container.scrollHeight - container.clientHeight;
    const distance = end - start;
    if (distance <= 0) return;

    const duration = Math.max(0, autoScrollDurationMs);
    const startTime = performance.now();

    const step = (now: number) => {
      const elapsed = now - startTime;
      const progress = duration === 0 ? 1 : Math.min(elapsed / duration, 1);
      const easeOutCubic = 1 - Math.pow(1 - progress, 3);
      container.scrollTop = start + distance * easeOutCubic;
      if (progress < 1) {
        requestAnimationFrame(step);
      }
    };

    requestAnimationFrame(step);
  }, [autoScrollDurationMs]);

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center px-4 bg-black/40">
      <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg max-w-lg w-full max-h-[80vh] flex flex-col">
        <div className="flex justify-between items-center p-4 border-b border-gray-200 dark:border-gray-700">
          <h2 className="text-lg font-semibold dark:text-white">{title || "Terms and Conditions"}</h2>
          <button
            className="text-gray-500 hover:text-gray-800 dark:hover:text-white text-2xl"
            onClick={onClose}
            aria-label="Close"
          >
            &times;
          </button>
        </div>
        <div
          ref={scrollRef}
          className="overflow-y-auto custom-scrollbar px-6 py-4 text-sm text-gray-700 dark:text-gray-200"
          onScroll={handleInternalScroll}
        >
          <div className="relative space-y-4">
            {hasBody ? (
              <ArticleBody value={body} />
            ) : (
              <p>Terms &amp; Conditions belum tersedia.</p>
            )}

            {!isAtBottom && (
              <div className="sticky bottom-3 z-10 flex justify-end">
                <button
                  type="button"
                  onClick={animateScrollToBottom}
                  aria-label="Scroll to bottom"
                  className="mr-1 w-10 h-10 rounded-full flex items-center justify-center bg-white text-gray-700 ring-1 ring-gray-200 shadow-sm hover:bg-gray-50 dark:bg-gray-900 dark:text-gray-200 dark:ring-gray-700 dark:hover:bg-white/5"
                >
                  <ArrowDown className="w-5 h-5" />
                </button>
              </div>
            )}
          </div>
        </div>
        <div className="flex justify-center p-4 border-t border-gray-200 dark:border-gray-700">
          <Button size="md" className="min-w-40 px-8" disabled={!isAtBottom} onClick={onAgree}>
            I Agree
          </Button>
        </div>
      </div>
    </div>
  );
}
