import { CompressOutlined } from '@ant-design/icons';
import { Button, Layout, Modal, Space, Typography } from 'antd';
import { useMemo, useRef, useState, type ReactNode } from 'react';
import { WindowUI, type WindowFrame } from '../../components/window';
import { BoardPage } from '../../features/board';
import { ComponentSamplesLayout } from '../../features/layout/component-sample-gallery';
import { SampleWidgetsLayout } from '../../features/layout/widget-sample-gallery';
import { renderSavedLayoutContent } from '../../features/layout/renderSavedLayoutContent';
import { HistoryPage } from '../../features/history';
import { PlanBoardChartsPage, PlanBoardPage, PlanSchedulePage, ReleaseReviewPage } from '../../features/planBoard';
import { useSearchLayer } from '../../layer';
import { useAppStore } from '../../store';
import { LayoutPlaygroundView } from '../../views/play/LayoutPlaygroundView';
import { AutomationTypeManagementPage } from './AutomationTypeManagementPage';
import { AutomationContextManagementPage } from './AutomationContextManagementPage';
import { ChatDefaultContextManagementPage } from './ChatDefaultContextManagementPage';
import { ResourceManagementPage } from './ResourceManagementPage';
import { SharedChatManagementPage } from './SharedChatManagementPage';
import { ChatTypeManagementPage } from './ChatTypeManagementPage';
import { ChatSourceChangesPage } from './ChatSourceChangesPage';
import { MainChatPanel } from './MainChatPanel';
import { PlayAppOverlay } from './PlayAppOverlay';
import { PreviewAppOverlay } from './PreviewAppOverlay';
import { SharedResourceManagementPage } from './SharedResourceManagementPage';
import { TokenSettingManagementPage } from './TokenSettingManagementPage';
import type { PreviewTargetDescriptor } from './previewRuntime';
import { useMainLayoutContext } from './layout/MainLayoutContext';
import { buildPlayPath } from './routes';
import {
  HIDDEN_COMPONENT_IDS,
  buildCascadeWindowFrames,
  buildGridWindowFrames,
  getDefaultWindowFrame,
  getPlanStatusFromWindowSelection,
} from './mainContent/windowLayout';
import type { MainContentProps } from './types';

const { Content } = Layout;
const { Paragraph, Text, Title } = Typography;

function parseWidgetSelectionId(selectionId: string): PreviewTargetDescriptor {
  const [targetType, componentId, sampleId] = selectionId.split(':');

  if (targetType !== 'widget' || !componentId) {
    return null;
  }

  return {
    type: 'widget',
    componentId,
    sampleId: sampleId || undefined,
  };
}

const SAVED_LAYOUT_WINDOW_SELECTION_PREFIX = 'page:play:layout-record:';
const PLAY_APP_SELECTION_PREFIX = 'page:play:app:';

function parseSavedLayoutSelectionId(selectionId: string) {
  return selectionId.startsWith(SAVED_LAYOUT_WINDOW_SELECTION_PREFIX)
    ? selectionId.slice(SAVED_LAYOUT_WINDOW_SELECTION_PREFIX.length)
    : null;
}

function parsePlayAppSelectionId(selectionId: string) {
  return selectionId.startsWith(PLAY_APP_SELECTION_PREFIX) ? selectionId.slice(PLAY_APP_SELECTION_PREFIX.length) : null;
}

export function MainContent({
  contentExpanded,
  sidebarOverlayActive = false,
  disableWindowLayer = false,
  onToggleContentExpanded,
  children,
}: MainContentProps) {
  const { setFocusedComponentId } = useAppStore();
  const { windowSelections, clearWindowSelection } = useSearchLayer();
  const {
    componentSampleEntries,
    widgetSampleEntries,
    componentSamples,
    widgetSamples,
    initialSelectedPlanId,
    initialSelectedWorkId,
    savedLayouts,
    setSavedLayouts,
  } = useMainLayoutContext();
  const stageRef = useRef<HTMLDivElement>(null);
  const [windowFrames, setWindowFrames] = useState<Record<string, WindowFrame>>({});
  const [windowZIndexes, setWindowZIndexes] = useState<Record<string, number>>({});
  const [isWindowLayoutModalOpen, setIsWindowLayoutModalOpen] = useState(false);
  const sampleEntryMap = useMemo(
    () =>
      new Map(
        [...componentSamples, ...widgetSamples].map((entry) => [
          `${entry.modulePath.includes('/widgets/') ? 'widget' : 'component'}:${entry.sampleMeta.componentId}:${entry.sampleMeta.id}`,
          entry,
        ]),
      ),
    [componentSamples, widgetSamples],
  );
  const previewAppSelection = useMemo(
    () => windowSelections.find((selection) => selection.id === 'page:preview:app') ?? null,
    [windowSelections],
  );
  const playAppSelection = useMemo(
    () => windowSelections.find((selection) => selection.id.startsWith(PLAY_APP_SELECTION_PREFIX)) ?? null,
    [windowSelections],
  );
  const regularWindowSelections = useMemo(
    () =>
      windowSelections.filter(
        (selection) => selection.id !== 'page:preview:app' && !selection.id.startsWith(PLAY_APP_SELECTION_PREFIX),
      ),
    [windowSelections],
  );
  const getWindowFrame = (instanceId: string, selectionId: string, index: number): WindowFrame =>
    windowFrames[instanceId] ?? getDefaultWindowFrame(selectionId, index);

  const getWindowZIndex = (instanceId: string, index: number) => windowZIndexes[instanceId] ?? index + 1;

  const activateWindow = (instanceId: string) => {
    setWindowZIndexes((previous) => {
      const highestZIndex = Math.max(0, ...Object.values(previous));
      return {
        ...previous,
        [instanceId]: highestZIndex + 1,
      };
    });
  };

  const getStageSize = () => {
    const stage = stageRef.current;

    if (!stage) {
      return null;
    }

    return {
      width: stage.clientWidth,
      height: stage.clientHeight,
    };
  };

  const applyCascadeWindowLayout = () => {
    const stageSize = getStageSize();

    if (!stageSize) {
      return;
    }

    const nextFrames = buildCascadeWindowFrames(windowSelections, stageSize);

    setWindowFrames((previous) => ({
      ...previous,
      ...nextFrames,
    }));
    setIsWindowLayoutModalOpen(false);
  };

  const applyGridWindowLayout = () => {
    const stageSize = getStageSize();

    if (!stageSize) {
      return;
    }

    const nextFrames = buildGridWindowFrames(windowSelections, stageSize);

    setWindowFrames((previous) => ({
      ...previous,
      ...nextFrames,
    }));
    setIsWindowLayoutModalOpen(false);
  };

  const handleFocusCapture = (target: EventTarget | null) => {
    if (!(target instanceof HTMLElement)) {
      return;
    }

    const focusedElement = target.closest<HTMLElement>('[data-focus-id]');
    setFocusedComponentId(focusedElement?.dataset.focusId ?? null);
  };

  const renderWindowSelectionContent = (selectionId: string, fallbackContent: ReactNode) => {
    const savedLayoutId = parseSavedLayoutSelectionId(selectionId);
    const savedLayout = savedLayoutId ? savedLayouts.find((item) => item.id === savedLayoutId) ?? null : null;

    if (savedLayoutId && savedLayout) {
      return renderSavedLayoutContent({
        layoutId: savedLayoutId,
        layout: savedLayout,
        savedLayouts,
        onSavedLayoutsChange: setSavedLayouts,
      });
    }

    if (selectionId === 'page:apis:components') {
      return (
        <ComponentSamplesLayout
          entries={componentSampleEntries}
          excludeComponentIds={HIDDEN_COMPONENT_IDS}
        />
      );
    }

    if (selectionId === 'page:apis:widgets') {
      return <SampleWidgetsLayout entries={widgetSampleEntries} />;
    }

    if (selectionId === 'page:plans:release') {
      return (
        <PlanBoardPage
          statusFilter="done"
          quickFilter="release-pending-main"
          initialSelectedPlanId={initialSelectedPlanId}
          initialSelectedWorkId={initialSelectedWorkId}
        />
      );
    }

    if (selectionId === 'page:plans:board') {
      return <BoardPage />;
    }

    if (selectionId === 'page:plans:release-review') {
      return <ReleaseReviewPage />;
    }

    if (selectionId === 'page:plans:charts') {
      return <PlanBoardChartsPage />;
    }

    if (selectionId === 'page:plans:schedule') {
      return <PlanSchedulePage />;
    }

    if (selectionId === 'page:plans:history') {
      return <HistoryPage />;
    }

    if (selectionId === 'page:plans:automation-type') {
      return <AutomationTypeManagementPage />;
    }

    if (selectionId === 'page:plans:automation-context') {
      return <AutomationContextManagementPage />;
    }

    if (selectionId === 'page:plans:token-setting') {
      return <TokenSettingManagementPage />;
    }

    if (selectionId === 'page:plans:shared-resource') {
      return <SharedResourceManagementPage />;
    }

    const planStatus = getPlanStatusFromWindowSelection(selectionId);

    if (planStatus) {
      return (
        <PlanBoardPage
          statusFilter={planStatus}
          quickFilter={null}
          initialSelectedPlanId={initialSelectedPlanId}
          initialSelectedWorkId={initialSelectedWorkId}
        />
      );
    }

    if (selectionId === 'page:chat:live') {
      return <MainChatPanel initialView="live" />;
    }


    if (selectionId === 'page:chat:errors') {
      return <MainChatPanel initialView="errors" />;
    }

    if (selectionId === 'page:chat:changes') {
      return <ChatSourceChangesPage />;
    }

    if (selectionId === 'page:chat:resources') {
      return <ResourceManagementPage />;
    }

    if (selectionId === 'page:chat:manage') {
      return <ChatTypeManagementPage />;
    }

    if (selectionId === 'page:chat:manage-defaults') {
      return <ChatDefaultContextManagementPage />;
    }

    if (selectionId === 'page:chat:manage-share') {
      return <SharedChatManagementPage />;
    }

    if (selectionId === 'page:play:layout') {
      return <LayoutPlaygroundView />;
    }

    return fallbackContent;
  };

  return (
    <Content
      className={[
        'app-main-content',
        contentExpanded ? 'app-main-content--expanded' : '',
        sidebarOverlayActive ? 'app-main-content--under-sidebar-overlay' : '',
      ]
        .filter(Boolean)
        .join(' ')}
      onClickCapture={(event) => {
        handleFocusCapture(event.target);
      }}
      onFocusCapture={(event) => {
        handleFocusCapture(event.target);
      }}
    >
      {contentExpanded ? (
        <Button
          type="text"
          className="app-main-content__restore"
          aria-label="전체화면 종료"
          icon={<CompressOutlined />}
          onClick={onToggleContentExpanded}
        />
      ) : null}
      <div className="app-main-layout">{children}</div>
      {!disableWindowLayer && previewAppSelection ? (
        <div className="app-main-preview-layer">
          <PreviewAppOverlay
            key={previewAppSelection.instanceId}
            pathname={buildPlayPath('cbt')}
            onClose={() => {
              clearWindowSelection(previewAppSelection.instanceId);
            }}
          />
        </div>
      ) : null}
      {!disableWindowLayer && playAppSelection ? (
        <div className="app-main-play-app-layer">
          <PlayAppOverlay
            key={playAppSelection.instanceId}
            appId={parsePlayAppSelectionId(playAppSelection.id) ?? ''}
            label={playAppSelection.label}
            onClose={() => {
              clearWindowSelection(playAppSelection.instanceId);
            }}
          />
        </div>
      ) : null}
      {!disableWindowLayer && regularWindowSelections.length > 0 ? (
        <div className="app-main-window-layer">
          <div ref={stageRef} className="app-main-window-layer__stage">
            {regularWindowSelections.map((windowSelection, index) => {
              const selectedWindowSample = sampleEntryMap.get(windowSelection.id) ?? null;
              const SelectedWindowSample = selectedWindowSample?.Sample ?? null;
              const fallbackContent = (
                <div className="app-main-window-layer__fallback">
                  <Text strong>{windowSelection.label}</Text>
                  <div className="app-main-window-layer__keywords">
                    {(windowSelection.keywords.length > 0 ? windowSelection.keywords : ['검색 선택']).map((keyword) => (
                      <Text key={`${windowSelection.instanceId}-${keyword}`} code>
                        {keyword}
                      </Text>
                    ))}
                  </div>
                </div>
              );

              const widgetPreviewTarget = parseWidgetSelectionId(windowSelection.id);
              const isWidgetWindow = widgetPreviewTarget?.type === 'widget';

              return (
                <WindowUI
                  key={windowSelection.instanceId}
                  title={windowSelection.label}
                  subtitle={isWidgetWindow ? undefined : windowSelection.group}
                  bodyClassName="app-main-window-layer__body"
                  frame={getWindowFrame(windowSelection.instanceId, windowSelection.id, index)}
                  onFrameChange={(nextFrame) => {
                    setWindowFrames((previous) => ({
                      ...previous,
                      [windowSelection.instanceId]: nextFrame,
                    }));
                  }}
                  zIndex={getWindowZIndex(windowSelection.instanceId, index)}
                  onActivate={() => {
                    activateWindow(windowSelection.instanceId);
                  }}
                  onOpenLayoutControls={
                    isWidgetWindow
                      ? undefined
                      : () => {
                          setIsWindowLayoutModalOpen(true);
                        }
                  }
                  className={`app-main-window-layer__window${isWidgetWindow ? ' app-main-window-layer__window--widget-preview' : ''}`}
                  onClose={() => {
                    clearWindowSelection(windowSelection.instanceId);
                  }}
                  showMaximizeControl={!isWidgetWindow}
                  minWidth={isWidgetWindow ? 320 : undefined}
                  minHeight={isWidgetWindow ? 240 : undefined}
                  compactHeader={isWidgetWindow}
                >
                  {isWidgetWindow && widgetPreviewTarget ? (
                    <div className="app-main-window-layer__sample app-main-window-layer__sample--fill">
                      <SampleWidgetsLayout
                        entries={widgetSampleEntries}
                        includeComponentIds={[widgetPreviewTarget.componentId]}
                        includeSampleIds={widgetPreviewTarget.sampleId ? [widgetPreviewTarget.sampleId] : []}
                        disableWidgetCardWrapper
                        singlePreviewMode
                      />
                    </div>
                  ) : SelectedWindowSample ? (
                    <div
                      className={`app-main-window-layer__sample ${
                        isWidgetWindow
                          ? 'app-main-window-layer__sample--fill'
                          : 'app-main-window-layer__sample--intrinsic'
                      }`}
                    >
                      <SelectedWindowSample
                        disableWidgetCardWrapper={isWidgetWindow}
                      />
                    </div>
                  ) : (
                    <div className="app-main-window-layer__sample">
                      {renderWindowSelectionContent(windowSelection.id, fallbackContent)}
                    </div>
                  )}
                </WindowUI>
              );
            })}
          </div>
        </div>
      ) : null}
      {!disableWindowLayer ? (
        <Modal
          title="윈도우 배치"
          open={isWindowLayoutModalOpen}
          onCancel={() => {
            setIsWindowLayoutModalOpen(false);
          }}
          footer={null}
        >
          <Space direction="vertical" size={16} style={{ width: '100%' }}>
            <div>
              <Title level={5}>추천 배치</Title>
              <Paragraph type="secondary" style={{ marginBottom: 12 }}>
                주요 창을 크게 두고 나머지 창은 겹치지 않게 순서대로 정렬합니다.
              </Paragraph>
              <Button block onClick={applyCascadeWindowLayout}>
                추천 배치 적용
              </Button>
            </div>
            <div>
              <Title level={5}>가득 채우기</Title>
              <Paragraph type="secondary" style={{ marginBottom: 12 }}>
                현재 열린 창을 작업 영역 기준 그리드로 꽉 차게 재배치합니다.
              </Paragraph>
              <Button block onClick={applyGridWindowLayout}>
                가득 채우기 적용
              </Button>
            </div>
          </Space>
        </Modal>
      ) : null}
    </Content>
  );
}
