import { useEffect, useRef, useState } from 'react';
import type { ChatComposerAttachment } from '../../mainChatPanel/types';

type PreviewItem = {
  id: string;
  label: string;
  url: string;
  kind: 'image' | 'video' | 'markdown' | 'code' | 'diff' | 'document' | 'pdf' | 'file';
  source: 'message' | 'context';
};

type UseConversationViewControllerOptions = {
  activeSessionId: string;
  activeView: 'chat' | 'runtime' | 'errors';
  isMobileViewport: boolean;
  previewItems: PreviewItem[];
  composerRef: { current: { focus: (options?: { cursor?: 'start' | 'end' | 'all' }) => void } | null };
  setActiveSystemStatus: (value: string | null) => void;
  setComposerAttachments: React.Dispatch<React.SetStateAction<ChatComposerAttachment[]>>;
  setCopiedMessageId: (value: number | null) => void;
  setDraft: React.Dispatch<React.SetStateAction<string>>;
  setIsResourceStripOpen: (value: boolean) => void;
  setIsSystemStatusPending: (value: boolean) => void;
};

export function useConversationViewController({
  activeSessionId,
  activeView,
  composerRef,
  isMobileViewport,
  previewItems,
  setActiveSystemStatus,
  setComposerAttachments,
  setCopiedMessageId,
  setDraft,
  setIsResourceStripOpen,
  setIsSystemStatusPending,
}: UseConversationViewControllerOptions) {
  const previousSessionIdRef = useRef(activeSessionId);
  const previousActiveViewRef = useRef(activeView);
  const hasInitializedComposerFocusRef = useRef(false);
  const [activePreviewId, setActivePreviewId] = useState<string | null>(null);
  const [activePreviewOverride, setActivePreviewOverride] = useState<PreviewItem | null>(null);
  const [isPreviewModalOpen, setIsPreviewModalOpen] = useState(false);
  const [previewModalTarget, setPreviewModalTarget] = useState<PreviewItem | null>(null);
  const [previewText, setPreviewText] = useState('');
  const [isPreviewLoading, setIsPreviewLoading] = useState(false);
  const [previewError, setPreviewError] = useState('');
  const [previewContentType, setPreviewContentType] = useState('');

  const activePreview = activePreviewOverride ?? previewItems.find((item) => item.id === activePreviewId) ?? previewItems[0] ?? null;

  useEffect(() => {
    if (!isPreviewModalOpen || !activePreview) {
      return;
    }

    setPreviewModalTarget(activePreview);
  }, [activePreview, isPreviewModalOpen]);

  useEffect(() => {
    const previousSessionId = previousSessionIdRef.current;
    const hasSessionChanged = previousSessionId !== activeSessionId;

    if (!hasSessionChanged) {
      return;
    }

    previousSessionIdRef.current = activeSessionId;

    // Draft restoration is handled by the panel layer per session. Keep this
    // hook focused on view-only resets so session changes do not wipe a
    // restored draft after the panel has reloaded it from storage.
    if (previousSessionId.trim() && !activeSessionId.trim()) {
      return;
    }

    setComposerAttachments([]);
    setCopiedMessageId(null);
    setActivePreviewId(null);
    setActivePreviewOverride(null);
    setIsPreviewModalOpen(false);
    setActiveSystemStatus(null);
    setIsSystemStatusPending(false);
    setIsResourceStripOpen(false);
  }, [
    activeSessionId,
    setActiveSystemStatus,
    setComposerAttachments,
    setCopiedMessageId,
    setDraft,
    setIsResourceStripOpen,
    setIsSystemStatusPending,
  ]);

  useEffect(() => {
    if (!activePreviewId || activePreviewOverride) {
      return;
    }

    if (previewItems.some((item) => item.id === activePreviewId)) {
      return;
    }

    setActivePreviewId(null);
    setIsPreviewModalOpen(false);
  }, [activePreviewId, activePreviewOverride, previewItems]);

  useEffect(() => {
    if (!previewModalTarget) {
      setPreviewText('');
      setPreviewError('');
      setPreviewContentType('');
      setIsPreviewLoading(false);
      return;
    }

    if (!isPreviewModalOpen) {
      return;
    }

    if (
      previewModalTarget.kind === 'image' ||
      previewModalTarget.kind === 'video' ||
      previewModalTarget.kind === 'pdf' ||
      previewModalTarget.kind === 'file'
    ) {
      setPreviewText('');
      setPreviewError('');
      setPreviewContentType('');
      setIsPreviewLoading(false);
      return;
    }

    const controller = new AbortController();
    setIsPreviewLoading(true);
    setPreviewError('');
    setPreviewContentType('');

    fetch(previewModalTarget.url, {
      cache: 'no-store',
      signal: controller.signal,
    })
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`${response.status} ${response.statusText}`);
        }

        setPreviewContentType(response.headers.get('content-type') ?? '');
        const text = await response.text();
        setPreviewText(text.slice(0, 20000));
      })
      .catch((error: unknown) => {
        if (controller.signal.aborted) {
          return;
        }

        setPreviewText('');
        setPreviewContentType('');
        setPreviewError(error instanceof Error ? error.message : 'preview를 가져오지 못했습니다.');
      })
      .finally(() => {
        if (!controller.signal.aborted) {
          setIsPreviewLoading(false);
        }
      });

    return () => {
      controller.abort();
    };
  }, [isPreviewModalOpen, previewModalTarget]);

  const handlePreviewModalAfterOpenChange = (open: boolean) => {
    if (open) {
      return;
    }

    setPreviewModalTarget(null);
    setPreviewText('');
    setPreviewError('');
    setPreviewContentType('');
    setIsPreviewLoading(false);
  };

  useEffect(() => {
    const previousActiveView = previousActiveViewRef.current;
    previousActiveViewRef.current = activeView;

    if (activeView !== 'chat' || isMobileViewport) {
      return;
    }

    const shouldFocusComposer = !hasInitializedComposerFocusRef.current || previousActiveView !== 'chat';
    hasInitializedComposerFocusRef.current = true;

    if (!shouldFocusComposer) {
      return;
    }

    composerRef.current?.focus({ cursor: 'end' });
  }, [activeView, composerRef, isMobileViewport]);

  useEffect(() => {
    if (activeView !== 'chat') {
      return undefined;
    }

    const handleWindowKeyDown = (event: KeyboardEvent) => {
      const isTextEntryTarget =
        event.target instanceof HTMLElement &&
        (event.target.isContentEditable ||
          ['input', 'textarea', 'select'].includes(event.target.tagName.toLowerCase()) ||
          event.target.closest('[contenteditable="true"]'));

      if (event.metaKey || event.ctrlKey || event.altKey || isTextEntryTarget) {
        return;
      }

      if (event.key === '/') {
        event.preventDefault();
        composerRef.current?.focus({ cursor: 'end' });
        return;
      }

      if (event.key.length === 1) {
        event.preventDefault();
        composerRef.current?.focus({ cursor: 'end' });
        setDraft((previous) => previous + event.key);
      }
    };

    window.addEventListener('keydown', handleWindowKeyDown);

    return () => {
      window.removeEventListener('keydown', handleWindowKeyDown);
    };
  }, [activeView, composerRef, setDraft]);

  return {
    activePreview,
    activePreviewId,
    isPreviewLoading,
    isPreviewModalOpen,
    previewModalTarget,
    previewContentType,
    previewError,
    previewText,
    handlePreviewModalAfterOpenChange,
    setActivePreviewId,
    setActivePreviewOverride,
    setIsPreviewModalOpen,
  };
}
