'use client';

import { Fragment, useEffect, useRef, useState } from 'react';
import MessageInput from './MessageInput';
import { File, Message } from './ChatWindow';
import MessageBox from './MessageBox';
import MessageBoxLoading from './MessageBoxLoading';
import { check } from 'drizzle-orm/gel-core';

const Chat = ({
  loading,
  messages,
  sendMessage,
  scrollTrigger,
  rewrite,
  fileIds,
  setFileIds,
  files,
  setFiles,
  optimizationMode,
  setOptimizationMode,
  focusMode,
  setFocusMode,
}: {
  messages: Message[];
  sendMessage: (
    message: string,
    options?: {
      messageId?: string;
      rewriteIndex?: number;
      suggestions?: string[];
    },
  ) => void;
  loading: boolean;
  scrollTrigger: number;
  rewrite: (messageId: string) => void;
  fileIds: string[];
  setFileIds: (fileIds: string[]) => void;
  files: File[];
  setFiles: (files: File[]) => void;
  optimizationMode: string;
  setOptimizationMode: (mode: string) => void;
  focusMode: string;
  setFocusMode: (mode: string) => void;
}) => {
  const [dividerWidth, setDividerWidth] = useState(0);
  const [isAtBottom, setIsAtBottom] = useState(true);
  const [manuallyScrolledUp, setManuallyScrolledUp] = useState(false);
  const dividerRef = useRef<HTMLDivElement | null>(null);
  const messageEnd = useRef<HTMLDivElement | null>(null);
  const SCROLL_THRESHOLD = 250; // pixels from bottom to consider "at bottom"

  // Check if user is at bottom of page
  useEffect(() => {
    const checkIsAtBottom = () => {
      const position = window.innerHeight + window.scrollY;
      const height = document.body.scrollHeight;
      const atBottom = position >= height - SCROLL_THRESHOLD;

      setIsAtBottom(atBottom);
    };

    // Initial check
    checkIsAtBottom();

    // Add scroll event listener
    window.addEventListener('scroll', checkIsAtBottom);

    return () => {
      window.removeEventListener('scroll', checkIsAtBottom);
    };
  }, []);

  // Detect wheel and touch events to identify user's scrolling direction
  useEffect(() => {
    const checkIsAtBottom = () => {
      const position = window.innerHeight + window.scrollY;
      const height = document.body.scrollHeight;
      const atBottom = position >= height - SCROLL_THRESHOLD;

      // If user scrolls to bottom, reset the manuallyScrolledUp flag
      if (atBottom) {
        setManuallyScrolledUp(false);
      }

      setIsAtBottom(atBottom);
    };

    const handleWheel = (e: WheelEvent) => {
      // Positive deltaY means scrolling down, negative means scrolling up
      if (e.deltaY < 0) {
        // User is scrolling up
        setManuallyScrolledUp(true);
      } else if (e.deltaY > 0) {
        checkIsAtBottom();
      }
    };

    const handleTouchStart = (e: TouchEvent) => {
      // Immediately stop auto-scrolling on any touch interaction
      setManuallyScrolledUp(true);
    };

    // Add event listeners
    window.addEventListener('wheel', handleWheel, { passive: true });
    window.addEventListener('touchstart', handleTouchStart, { passive: true });

    return () => {
      window.removeEventListener('wheel', handleWheel);
      window.removeEventListener('touchstart', handleTouchStart);
    };
  }, [isAtBottom]);

  useEffect(() => {
    const updateDividerWidth = () => {
      if (dividerRef.current) {
        setDividerWidth(dividerRef.current.scrollWidth);
      }
    };

    updateDividerWidth();

    window.addEventListener('resize', updateDividerWidth);

    return () => {
      window.removeEventListener('resize', updateDividerWidth);
    };
  });

  // Scroll when user sends a message
  useEffect(() => {
    const scroll = () => {
      messageEnd.current?.scrollIntoView({ behavior: 'smooth' });
    };

    if (messages.length === 1) {
      document.title = `${messages[0].content.substring(0, 30)} - Perplexica`;
    }

    // Always scroll when user sends a message
    if (messages[messages.length - 1]?.role === 'user') {
      scroll();
      setIsAtBottom(true); // Reset to true when user sends a message
      setManuallyScrolledUp(false); // Reset manually scrolled flag when user sends a message
    }
  }, [messages]);

  // Auto-scroll for assistant responses only if user is at bottom and hasn't manually scrolled up
  useEffect(() => {
    const position = window.innerHeight + window.scrollY;
    const height = document.body.scrollHeight;
    const atBottom = position >= height - SCROLL_THRESHOLD;
    setIsAtBottom(atBottom);

    if (isAtBottom && !manuallyScrolledUp && messages.length > 0) {
      messageEnd.current?.scrollIntoView({ behavior: 'smooth' });
    }
  }, [scrollTrigger, isAtBottom, messages.length, manuallyScrolledUp]);

  return (
    <div className="flex flex-col space-y-6 pt-8 pb-48 sm:mx-4 md:mx-8">
      {messages.map((msg, i) => {
        const isLast = i === messages.length - 1;

        return (
          <Fragment key={msg.messageId}>
            <MessageBox
              key={i}
              message={msg}
              messageIndex={i}
              history={messages}
              loading={loading}
              dividerRef={isLast ? dividerRef : undefined}
              isLast={isLast}
              rewrite={rewrite}
              sendMessage={sendMessage}
            />
            {!isLast && msg.role === 'assistant' && (
              <div className="h-px w-full bg-light-secondary dark:bg-dark-secondary" />
            )}
          </Fragment>
        );
      })}
      {loading && <MessageBoxLoading />}
      <div ref={messageEnd} className="h-0" />

      {dividerWidth > 0 && (
        <div
          className="bottom-24 lg:bottom-10 fixed z-40"
          style={{ width: dividerWidth }}
        >
          {/* Scroll to bottom button - appears above the MessageInput when user has scrolled up */}
          {manuallyScrolledUp && !isAtBottom && (
            <div className="absolute -top-14 right-2 z-10">
              <button
                onClick={() => {
                  setManuallyScrolledUp(false);
                  setIsAtBottom(true);
                  messageEnd.current?.scrollIntoView({ behavior: 'smooth' });
                }}
                className="bg-[#24A0ED] text-white hover:bg-opacity-85 transition duration-100 rounded-full px-4 py-2 shadow-lg flex items-center justify-center"
                aria-label="Scroll to bottom"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-5 w-5 mr-1"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    fillRule="evenodd"
                    d="M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z"
                    clipRule="evenodd"
                    transform="rotate(180 10 10)"
                  />
                </svg>
                <span className="text-sm">Scroll to bottom</span>
              </button>
            </div>
          )}

          <MessageInput
            firstMessage={messages.length === 0}
            loading={loading}
            sendMessage={sendMessage}
            fileIds={fileIds}
            setFileIds={setFileIds}
            files={files}
            setFiles={setFiles}
            optimizationMode={optimizationMode}
            setOptimizationMode={setOptimizationMode}
            focusMode={focusMode}
            setFocusMode={setFocusMode}
          />
        </div>
      )}
    </div>
  );
};

export default Chat;
