import { memo, useEffect, useRef, useState } from 'react';
import {
  ChevronDown,
  LoaderCircle,
  MoreHorizontal,
  PanelLeftClose,
  PanelLeftOpen,
  PencilLine,
  Plus,
  Trash2,
} from 'lucide-react';
import type { ChatHistoryBucket } from './types';
import blueLogo from '../../assets/images/login/blue_logo.png';
import { useI18n } from '../../i18n';

type ChatHistoryPanelProps = {
  buckets: ChatHistoryBucket[];
  selectedConversationId?: string;
  loading?: boolean;
  onNewChat?: () => void;
  onSelectConversation?: (conversationId: string) => void;
  onRenameConversation?: (conversationId: string) => void;
  onDeleteConversation?: (conversationId: string) => void;
};

type MenuState = {
  conversationId: string;
} | null;

function cx(...classes: Array<string | false | null | undefined>): string {
  return classes.filter(Boolean).join(' ');
}

function ChatHistoryPanel({
  buckets,
  selectedConversationId,
  loading,
  onNewChat,
  onSelectConversation,
  onRenameConversation,
  onDeleteConversation,
}: ChatHistoryPanelProps) {
  const { t } = useI18n();
  const panelRef = useRef<HTMLElement | null>(null);
  const [collapsedBuckets, setCollapsedBuckets] = useState<Record<string, boolean>>({});
  const [menuState, setMenuState] = useState<MenuState>(null);
  const [isCompact, setIsCompact] = useState(false);

  useEffect(() => {
    setCollapsedBuckets((current) => {
      const next: Record<string, boolean> = {};
      const currentKeys = Object.keys(current);
      let changed = currentKeys.length !== buckets.length;

      for (const bucket of buckets) {
        next[bucket.key] = current[bucket.key] ?? false;
        if (current[bucket.key] !== next[bucket.key]) {
          changed = true;
        }
      }

      return changed ? next : current;
    });
  }, [buckets]);

  useEffect(() => {
    if (!menuState) {
      return;
    }

    const handlePointerDown = (event: PointerEvent) => {
      const target = event.target as HTMLElement | null;
      if (!target) {
        setMenuState(null);
        return;
      }

      if (target.closest('[data-chat-history-menu="true"]')) {
        return;
      }

      if (!panelRef.current?.contains(target)) {
        setMenuState(null);
        return;
      }

      if (!target.closest('[data-chat-history-menu-toggle="true"]')) {
        setMenuState(null);
      }
    };

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setMenuState(null);
      }
    };

    document.addEventListener('pointerdown', handlePointerDown);
    document.addEventListener('keydown', handleEscape);

    return () => {
      document.removeEventListener('pointerdown', handlePointerDown);
      document.removeEventListener('keydown', handleEscape);
    };
  }, [menuState]);

  const panelWidthClass = isCompact ? 'md:w-[70px] lg:w-[70px]' : 'md:w-[240px] lg:w-[252px]';
  const toggleSidebarLabel = isCompact
    ? t('conversation.historyPanel.expandSidebar')
    : t('conversation.historyPanel.collapseSidebar');

  return (
    <aside
      ref={panelRef}
      className={cx(
        'flex h-full min-h-0 w-full flex-none flex-col transition-[width] duration-300',
        panelWidthClass,
      )}
    >
      <div className="flex h-full min-h-0 flex-col bg-[#fbfcfe] px-3 py-3 dark:border-[#2a2a2d] dark:bg-[#1b1b1d]">
        <div className={cx('flex items-center justify-between gap-3', isCompact && 'flex-col items-center')}>
          {!isCompact ? (
            <div className={cx('flex min-w-0 items-center gap-3', isCompact && 'flex-col gap-2')}>
              <div className="flex h-12 w-12 flex-none items-center justify-center overflow-hidden rounded-2xl border border-white bg-white shadow-[0_6px_16px_rgba(15,23,42,0.08)]">
                <img className="h-full w-full object-cover" src={blueLogo} alt="YINIAN" />
              </div>
              <div className="truncate whitespace-nowrap text-[20px] font-semibold tracking-[0.06em] text-[#111827] dark:text-gray-50">
                YINIAN
              </div>
            </div>
          ) : null}

          <button
            type="button"
            className={cx(
              'inline-flex h-12 w-12 items-center justify-center rounded-lg border text-[#64748b] transition-colors hover:text-[#111827] dark:border-[#2a2a2d] dark:text-gray-300 dark:hover:border-[#3a3a3f] dark:hover:text-gray-100',
              isCompact ? 'border-[#e3eaf3]' : 'border-transparent',
            )}
            title={toggleSidebarLabel}
            aria-label={toggleSidebarLabel}
            onClick={() => {
              setMenuState(null);
              setIsCompact((current) => !current);
            }}
          >
            {isCompact ? <PanelLeftOpen /> : <PanelLeftClose />}
          </button>
        </div>

        <button
          type="button"
          className={cx(
            'mt-4 inline-flex h-12 items-center justify-center gap-2 rounded-lg border border-[#e3eaf3] bg-white px-4 text-[15px] font-medium text-[#111827] shadow-[0_4px_14px_rgba(15,23,42,0.05)] transition-all hover:-translate-y-px hover:border-[#d5e3f4] hover:shadow-[0_10px_24px_rgba(15,23,42,0.08)] dark:border-[#2a2a2d] dark:bg-[#202024] dark:text-gray-100 dark:hover:border-[#3a3a3f]',
            isCompact && 'px-0',
          )}
          title={t('conversation.newConversation')}
          aria-label={t('conversation.newConversation')}
          onClick={onNewChat}
        >
          <Plus className="h-5 w-5 flex-none" />
          {!isCompact ? <span className="whitespace-nowrap">{t('conversation.newConversation')}</span> : null}
        </button>

        <div className="min-h-0 flex-1 overflow-y-auto pt-4">
          {loading ? (
            <div className="flex flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-[#dbe7f4] bg-white p-4 text-sm text-[#94a3b8] shadow-[0_4px_14px_rgba(15,23,42,0.04)] dark:border-[#2a2a2d] dark:bg-[#202024] dark:text-gray-400">
              <LoaderCircle className="h-5 w-5 animate-spin text-[#8bb7ff]" />
              {t('conversation.historyPanel.loading')}
            </div>
          ) : null}

          {!isCompact
            ? buckets.map((bucket) => {
                const isCollapsed = collapsedBuckets[bucket.key] ?? false;

                return (
                  <section key={bucket.key} className="mb-4 last:mb-0">
                    {bucket.sessions.length ? (
                      <button
                        type="button"
                        className="flex w-full items-center justify-between rounded-lg border border-[#e5edf7] p-2 text-left transition-colors dark:border-[#2f3136] dark:bg-[#202024]"
                        aria-expanded={!isCollapsed}
                        onClick={() => {
                          setMenuState(null);
                          setCollapsedBuckets((current) => ({
                            ...current,
                            [bucket.key]: !current[bucket.key],
                          }));
                        }}
                      >
                        <div className="flex items-center gap-2">
                          <span className="text-[14px] font-medium text-[#94a3b8] dark:text-gray-400">{bucket.label}</span>
                          <span className="text-[11px] text-[#c2cad6] dark:text-gray-600">{bucket.sessions.length}</span>
                        </div>
                        <ChevronDown
                          className={cx(
                            'h-4 w-4 text-[#b2bccb] transition-transform duration-200 dark:text-gray-500',
                            isCollapsed && '-rotate-90',
                          )}
                        />
                      </button>
                    ) : null}

                    {!isCollapsed ? (
                      <ul className="mt-2 space-y-2">
                        {bucket.sessions.map((session) => {
                          const isActive = session.conversationId === selectedConversationId;
                          const isMenuOpen = menuState?.conversationId === session.conversationId;
                          const canDelete = Boolean(onDeleteConversation) && session.canDelete !== false;

                          return (
                            <li key={session.conversationId}>
                              <div className="group relative">
                                <button
                                  type="button"
                                  className={cx(
                                    'flex w-full items-center gap-2 rounded-lg px-2 py-2 pr-11 text-left text-[12px] transition-all',
                                    isActive
                                      ? 'text-[#111827] shadow-[0_4px_14px_rgba(15,23,42,0.06)] dark:text-gray-50'
                                      : 'border border-transparent text-[#5b6472] hover:border-[#e5edf7] hover:bg-white hover:text-[#111827] hover:shadow-[0_4px_14px_rgba(15,23,42,0.05)] dark:text-gray-400 dark:hover:border-[#2a2a2d] dark:hover:bg-[#202024] dark:hover:text-gray-100',
                                  )}
                                  onClick={() => {
                                    setMenuState(null);
                                    onSelectConversation?.(session.conversationId);
                                  }}
                                >
                                  <span
                                    className={cx(
                                      'h-2 w-2 flex-none rounded-full transition-colors',
                                      isActive ? 'bg-[#9fc4ff]' : 'bg-[#c7dcff]',
                                    )}
                                  />
                                  <span className="min-w-0 flex-1 truncate">{session.title}</span>
                                </button>

                                <button
                                  type="button"
                                  data-chat-history-menu-toggle="true"
                                  className={cx(
                                    'absolute right-2 top-1/2 inline-flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full border border-transparent text-[#9aa5b1] transition-all hover:bg-[#f1f5f9] hover:text-[#111827] dark:hover:bg-[#2a2a2d] dark:hover:text-gray-100',
                                    isActive || isMenuOpen
                                      ? 'opacity-100'
                                      : 'pointer-events-none opacity-0 group-hover:pointer-events-auto group-hover:opacity-100',
                                  )}
                                  title={t('conversation.historyPanel.moreActions')}
                                  aria-label={t('conversation.historyPanel.moreActions')}
                                  onClick={(event) => {
                                    event.stopPropagation();
                                    setMenuState((current) =>
                                      current?.conversationId === session.conversationId
                                        ? null
                                        : { conversationId: session.conversationId },
                                    );
                                  }}
                                >
                                  <MoreHorizontal className="h-4 w-4" />
                                </button>

                                {isMenuOpen ? (
                                  <div
                                    data-chat-history-menu="true"
                                    className="absolute right-1 top-full z-20 mt-2 w-32 overflow-hidden rounded-[14px] border border-[#e5edf7] bg-white shadow-[0_16px_28px_rgba(15,23,42,0.12)] dark:border-[#2f3136] dark:bg-[#202024]"
                                  >
                                    <button
                                      type="button"
                                      className="flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm text-[#111827] transition-colors hover:bg-[#f4f8fc] dark:text-gray-100 dark:hover:bg-[#2a2a2d]"
                                      disabled={!onRenameConversation}
                                      onClick={(event) => {
                                        event.stopPropagation();
                                        setMenuState(null);
                                        onRenameConversation?.(session.conversationId);
                                      }}
                                    >
                                      <PencilLine className="h-4 w-4 text-[#94a3b8]" />
                                      {t('conversation.historyPanel.rename')}
                                    </button>
                                    {canDelete ? (
                                      <button
                                        type="button"
                                        className="flex w-full items-center gap-2 border-t border-[#eef3f9] px-3 py-2.5 text-left text-sm text-[#ef4444] transition-colors hover:bg-[#fff5f5] disabled:cursor-not-allowed disabled:text-[#f5a2a2] dark:border-[#2f3136] dark:hover:bg-[#2a2a2d]"
                                        onClick={(event) => {
                                          event.stopPropagation();
                                          setMenuState(null);
                                          onDeleteConversation?.(session.conversationId);
                                        }}
                                      >
                                        <Trash2 className="h-4 w-4" />
                                        {t('conversation.historyPanel.delete')}
                                      </button>
                                    ) : null}
                                  </div>
                                ) : null}
                              </div>
                            </li>
                          );
                        })}
                      </ul>
                    ) : null}
                  </section>
                );
              })
            : null}
        </div>
      </div>
    </aside>
  );
}

export default memo(ChatHistoryPanel);
