import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  ArrowsAltOutlined,
  DeleteOutlined,
  EditOutlined,
  PlusOutlined,
  ReloadOutlined,
  SaveOutlined,
  ShrinkOutlined,
  UnorderedListOutlined,
} from '@ant-design/icons';
import { Alert, Button, Card, Empty, Form, Input, List, Modal, Segmented, Space, Switch, Tag, Typography } from 'antd';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { MarkdownPreviewContent } from '../../components/markdownPreview';
import {
  deleteChatDefaultContext,
  pruneChatRoomContextSettings,
  pruneChatTypeDefaultSelections,
  upsertChatDefaultContext,
  useChatContextSettingsRegistry,
  type ChatDefaultContextRecord,
} from './chatContextSettingsAccess';
import { confirmWithKeyboard } from './modalKeyboard';
import { useTokenAccess } from './tokenAccess';
import './ChatDefaultContextManagementPage.css';

const { Text, Title } = Typography;

type ChatDefaultContextFormValue = {
  id?: string;
  title: string;
  content: string;
  enabled: boolean;
};

const EMPTY_FORM_VALUE: ChatDefaultContextFormValue = {
  title: '',
  content: '',
  enabled: true,
};

function toFormValue(record: ChatDefaultContextRecord | null): ChatDefaultContextFormValue {
  if (!record) {
    return EMPTY_FORM_VALUE;
  }

  return {
    id: record.id,
    title: record.title,
    content: record.content,
    enabled: record.enabled,
  };
}

export function ChatDefaultContextManagementPage() {
  const { hasAccess } = useTokenAccess();
  const [searchParams] = useSearchParams();
  const {
    defaultContexts,
    chatTypeDefaults,
    roomContexts,
    isLoading,
    hasLoadedFromServer,
    storeSource,
    lastLoadedAt,
    lastFailedAt,
    errorMessage: contextSettingsErrorMessage,
    reload,
    setStore,
  } = useChatContextSettingsRegistry();
  const [selectedContextId, setSelectedContextId] = useState<string | null>(defaultContexts[0]?.id ?? null);
  const [isMobileViewport, setIsMobileViewport] = useState(false);
  const [mobileView, setMobileView] = useState<'edit' | 'preview'>('edit');
  const [detailMode, setDetailMode] = useState<'list' | 'detail'>('list');
  const [maximizedPane, setMaximizedPane] = useState<'none' | 'edit' | 'preview'>('none');
  const [isCreating, setIsCreating] = useState(false);
  const [saveErrorMessage, setSaveErrorMessage] = useState('');
  const [isReloading, setIsReloading] = useState(false);
  const [form] = Form.useForm<ChatDefaultContextFormValue>();
  const [modalApi, modalContextHolder] = Modal.useModal();
  const lastHydratedFormKeyRef = useRef('');

  const selectedContext = useMemo(
    () => defaultContexts.find((item) => item.id === selectedContextId) ?? null,
    [defaultContexts, selectedContextId],
  );
  const requestedContextId = searchParams.get('contextId')?.trim() ?? '';
  const shouldRenderServerList = hasLoadedFromServer && !contextSettingsErrorMessage;
  const isServerDataReadyForEditing = hasLoadedFromServer && !contextSettingsErrorMessage && storeSource === 'server';

  useEffect(() => {
    if (selectedContextId && defaultContexts.some((item) => item.id === selectedContextId)) {
      return;
    }

    setSelectedContextId(defaultContexts[0]?.id ?? null);
  }, [defaultContexts, selectedContextId]);

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

    if (!defaultContexts.some((item) => item.id === requestedContextId)) {
      return;
    }

    setIsCreating(false);
    setSelectedContextId(requestedContextId);
    setDetailMode('detail');
    setMaximizedPane('none');
    setMobileView('edit');
  }, [defaultContexts, requestedContextId]);

  useEffect(() => {
    if (detailMode !== 'detail') {
      lastHydratedFormKeyRef.current = '';
      return;
    }

    const nextFormKey = isCreating ? '__create__' : selectedContext?.id ?? '__empty__';

    if (lastHydratedFormKeyRef.current === nextFormKey) {
      return;
    }

    lastHydratedFormKeyRef.current = nextFormKey;
    form.resetFields();
    form.setFieldsValue(toFormValue(isCreating ? null : selectedContext));
  }, [detailMode, form, isCreating, selectedContext?.id]);

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }

    const mediaQuery = window.matchMedia('(max-width: 960px)');
    const update = () => {
      setIsMobileViewport(mediaQuery.matches);
      if (!mediaQuery.matches) {
        setMobileView('edit');
      }
    };

    update();
    mediaQuery.addEventListener('change', update);

    return () => {
      mediaQuery.removeEventListener('change', update);
    };
  }, []);

  const handleReload = async () => {
    setIsReloading(true);
    setSaveErrorMessage('');
    try {
      await reload();
    } catch (error) {
      setSaveErrorMessage(error instanceof Error ? error.message : '공통 문맥 재조회에 실패했습니다.');
    } finally {
      setIsReloading(false);
    }
  };

  const moveDefaultContextInList = async (contextId: string, direction: 'up' | 'down') => {
    const currentIndex = defaultContexts.findIndex((item) => item.id === contextId);

    if (currentIndex < 0) {
      return;
    }

    const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1;

    if (targetIndex < 0 || targetIndex >= defaultContexts.length) {
      return;
    }

    const reorderedDefaultContexts = [...defaultContexts];
    const [movedItem] = reorderedDefaultContexts.splice(currentIndex, 1);

    reorderedDefaultContexts.splice(targetIndex, 0, movedItem);

    const nextDefaultContexts = reorderedDefaultContexts.map((item, index) => ({
      ...item,
      sortOrder: index + 1,
    }));

    setSaveErrorMessage('');

    try {
      const savedStore = await setStore({
        defaultContexts: nextDefaultContexts,
        chatTypeDefaults,
        roomContexts,
      });

      setSelectedContextId((currentSelectedId) => {
        if (currentSelectedId && savedStore.defaultContexts.some((item) => item.id === currentSelectedId)) {
          return currentSelectedId;
        }

        return contextId;
      });
    } catch (error) {
      setSaveErrorMessage(error instanceof Error ? error.message : '공통 문맥 순서 변경에 실패했습니다.');
    }
  };

  const openCreateForm = () => {
    setIsCreating(true);
    setSelectedContextId(null);
    setDetailMode('detail');
    setMaximizedPane('none');
    setMobileView('edit');
    form.resetFields();
    form.setFieldsValue(EMPTY_FORM_VALUE);
  };

  const openDetail = (contextId: string) => {
    setIsCreating(false);
    setSelectedContextId(contextId);
    setDetailMode('detail');
    setMaximizedPane('none');
    setMobileView('edit');
  };

  const closeDetail = () => {
    setIsCreating(false);
    setDetailMode('list');
    setMaximizedPane('none');
    setMobileView('edit');
  };

  const handleDelete = async () => {
    if (!selectedContext) {
      return;
    }

    const confirmed = await confirmWithKeyboard(modalApi, {
      title: `"${selectedContext.title}" 공통 문맥을 삭제할까요?`,
      okText: '삭제',
      cancelText: '취소',
      okButtonProps: { danger: true },
    });

    if (!confirmed) {
      return;
    }

    const nextDefaultContexts = deleteChatDefaultContext(defaultContexts, selectedContext.id);
    const nextChatTypeDefaults = pruneChatTypeDefaultSelections(chatTypeDefaults, selectedContext.id);
    const nextRoomContexts = pruneChatRoomContextSettings(roomContexts, selectedContext.id);

    await setStore({
      defaultContexts: nextDefaultContexts,
      chatTypeDefaults: nextChatTypeDefaults,
      roomContexts: nextRoomContexts,
    });
    setSelectedContextId(nextDefaultContexts[0]?.id ?? null);
    setIsCreating(false);
    setDetailMode('list');
    form.resetFields();
    form.setFieldsValue(EMPTY_FORM_VALUE);
  };

  if (!hasAccess) {
    return (
      <>
        {modalContextHolder}
        <Card title="공통 문맥 관리" className="chat-type-management-page">
          <Alert
            showIcon
            type="warning"
            message="관리 페이지는 토큰 등록 사용자만 사용할 수 있습니다."
            description="설정 > 토큰 관리에서 권한 토큰을 등록한 뒤 공통 문맥을 관리하세요."
          />
        </Card>
      </>
    );
  }

  return (
    <div
      className={`chat-type-management-page chat-default-context-management-page${
        detailMode === 'detail' ? ' chat-type-management-page--detail' : ''
      }${maximizedPane !== 'none' ? ' chat-type-management-page--pane-maximized' : ''}${
        isMobileViewport ? ` chat-type-management-page--mobile-view-${mobileView}` : ''
      }`}
    >
      {modalContextHolder}
      {detailMode === 'list' ? (
        <Card
          title="공통 문맥 관리"
          className="chat-type-management-page__card"
          extra={
            <Space size={8} wrap>
              <Button
                shape="circle"
                icon={<ReloadOutlined />}
                aria-label="새로고침"
                title="새로고침"
                onClick={() => {
                  void handleReload();
                }}
                loading={isReloading}
              />
              <Button icon={<PlusOutlined />} onClick={openCreateForm} disabled={!isServerDataReadyForEditing}>
                신규 공통 문맥
              </Button>
            </Space>
          }
        >
          <div className="chat-type-management-page__list">
            <div className="chat-type-management-page__list-scroll">
              {saveErrorMessage ? <Alert showIcon type="error" message={saveErrorMessage} /> : null}
              {contextSettingsErrorMessage ? (
                <Alert
                  showIcon
                  type="error"
                  message="공통 문맥 목록을 서버에서 불러오지 못했습니다."
                  description={
                    <Space direction="vertical" size={8}>
                      <Text>{contextSettingsErrorMessage}</Text>
                      <Space size={8} wrap>
                        <Button
                          onClick={() => {
                            void handleReload().catch(() => undefined);
                          }}
                          loading={isReloading}
                        >
                          다시 불러오기
                        </Button>
                        {lastLoadedAt ? (
                          <Text type="secondary">{`마지막 정상 동기화: ${new Date(lastLoadedAt).toLocaleString()}`}</Text>
                        ) : (
                          <Text type="secondary">정상 동기화 이력이 없어 부분 목록을 대신 보여주지 않습니다.</Text>
                        )}
                        {lastFailedAt ? (
                          <Text type="secondary">{`마지막 실패: ${new Date(lastFailedAt).toLocaleString()}`}</Text>
                        ) : null}
                      </Space>
                    </Space>
                  }
                />
              ) : null}
              <div className="chat-type-management-page__list-header">
                <Title level={5}>등록 공통 문맥</Title>
                <Space size={8} wrap>
                  <Text type="secondary">{shouldRenderServerList ? `${defaultContexts.length}건` : '서버 확인 전'}</Text>
                  {isLoading ? <Text type="secondary">서버 동기화 중</Text> : null}
                  {shouldRenderServerList && lastLoadedAt ? (
                    <Text type="secondary">{`서버 기준 ${new Date(lastLoadedAt).toLocaleTimeString()}`}</Text>
                  ) : null}
                  {!shouldRenderServerList && !contextSettingsErrorMessage ? (
                    <Text type="secondary">표시는 `/api/chat-context-settings` 최신 응답 기준입니다.</Text>
                  ) : null}
                </Space>
              </div>
              {shouldRenderServerList && defaultContexts.length > 0 ? (
                <List
                  dataSource={defaultContexts}
                  renderItem={(item) => {
                    const itemIndex = defaultContexts.findIndex((context) => context.id === item.id);
                    const canMoveUp = itemIndex > 0;
                    const canMoveDown = itemIndex >= 0 && itemIndex < defaultContexts.length - 1;

                    return (
                      <List.Item
                        className={
                          item.id === selectedContextId
                            ? 'chat-type-management-page__item chat-type-management-page__item--active'
                            : 'chat-type-management-page__item'
                        }
                      >
                        <div className="chat-type-management-page__item-main">
                          <Space size={[8, 8]} wrap>
                            <Text strong>{item.title}</Text>
                            <Tag color="cyan">정렬 {item.sortOrder}</Tag>
                            <Tag color={item.enabled ? 'green' : 'default'}>{item.enabled ? '사용' : '중지'}</Tag>
                          </Space>
                          <div className="chat-type-management-page__item-description">
                            {item.content ? <MarkdownPreviewContent content={item.content} maxBlocks={3} /> : '본문 없음'}
                          </div>
                          <div className="chat-type-management-page__item-actions">
                            <Button
                              icon={<ArrowUpOutlined />}
                              disabled={!isServerDataReadyForEditing || !canMoveUp}
                              onClick={(event) => {
                                event.stopPropagation();
                                void moveDefaultContextInList(item.id, 'up');
                              }}
                            >
                              위로 이동
                            </Button>
                            <Button
                              icon={<ArrowDownOutlined />}
                              disabled={!isServerDataReadyForEditing || !canMoveDown}
                              onClick={(event) => {
                                event.stopPropagation();
                                void moveDefaultContextInList(item.id, 'down');
                              }}
                            >
                              아래로 이동
                            </Button>
                            <Button
                              type="default"
                              icon={<EditOutlined />}
                              disabled={!isServerDataReadyForEditing}
                              onClick={(event) => {
                                event.stopPropagation();
                                openDetail(item.id);
                              }}
                            >
                              상세 보기
                            </Button>
                          </div>
                        </div>
                      </List.Item>
                    );
                  }}
                />
              ) : isLoading && !hasLoadedFromServer ? (
                <Alert showIcon type="info" message="공통 문맥 목록을 서버에서 불러오는 중입니다." />
              ) : (
                <Empty
                  description={
                    contextSettingsErrorMessage
                      ? '서버 동기화 실패 상태입니다. 재조회 후 다시 확인해 주세요.'
                      : hasLoadedFromServer
                        ? '등록된 공통 문맥이 없습니다.'
                        : '서버 기준 공통 문맥을 아직 확인하지 못했습니다.'
                  }
                />
              )}
            </div>
          </div>
        </Card>
      ) : (
        <Card
          title={isCreating ? '공통 문맥 등록' : '공통 문맥 상세'}
          className={`chat-type-management-page__card${
            maximizedPane !== 'none' ? ' chat-type-management-page__card--pane-maximized' : ''
          }`}
          extra={
            <Space size={6} className="chat-type-management-page__header-actions" wrap>
              <Button
                shape="circle"
                icon={<ReloadOutlined />}
                aria-label="새로고침"
                title="새로고침"
                onClick={() => {
                  void handleReload();
                }}
                loading={isReloading}
              />
              <Button
                type="primary"
                shape="circle"
                icon={<SaveOutlined />}
                aria-label={isCreating ? '등록' : '수정 저장'}
                disabled={!isServerDataReadyForEditing}
                onClick={() => {
                  void form.submit();
                }}
              />
              <Button
                shape="circle"
                icon={<PlusOutlined />}
                aria-label="새 입력"
                onClick={openCreateForm}
                disabled={!isServerDataReadyForEditing}
              />
              {!isCreating && selectedContext ? (
                <Button
                  danger
                  shape="circle"
                  icon={<DeleteOutlined />}
                  aria-label="삭제"
                  disabled={!isServerDataReadyForEditing}
                  onClick={() => {
                    void handleDelete();
                  }}
                />
              ) : null}
              <Button shape="circle" icon={<UnorderedListOutlined />} aria-label="목록 가기" onClick={closeDetail} />
            </Space>
          }
        >
          <div className="chat-type-management-page__editor">
            {saveErrorMessage ? <Alert showIcon type="error" message={saveErrorMessage} /> : null}
            {contextSettingsErrorMessage ? <Alert showIcon type="error" message={contextSettingsErrorMessage} /> : null}
            {!isServerDataReadyForEditing ? (
              <Alert
                showIcon
                type="warning"
                message="서버 최신 공통 문맥을 확인한 뒤에만 수정할 수 있습니다."
                description="부분 목록이나 오래된 상태로 저장해 서버 값이 덮어써지는 경로를 막기 위해, 서버 동기화가 완료되기 전에는 저장을 제한합니다."
              />
            ) : null}
            <Form
              className="chat-type-management-page__editor-form"
              layout="vertical"
              form={form}
              initialValues={EMPTY_FORM_VALUE}
              onFinish={async (values) => {
                setSaveErrorMessage('');

                try {
                  const nextDefaultContexts = upsertChatDefaultContext(defaultContexts, values);
                  const savedContext = nextDefaultContexts.find((item) => item.id === values.id || item.title === values.title) ?? null;

                  await setStore({
                    defaultContexts: nextDefaultContexts,
                    chatTypeDefaults,
                    roomContexts,
                  });
                  setIsCreating(false);
                  setSelectedContextId(savedContext?.id ?? null);
                  setDetailMode('detail');
                } catch (error) {
                  setSaveErrorMessage(error instanceof Error ? error.message : '공통 문맥 저장에 실패했습니다.');
                }
              }}
            >
              <Form.Item name="id" hidden>
                <Input />
              </Form.Item>
              <div className="chat-type-management-page__editor-scroll">
                <div
                  className={`chat-type-management-page__meta-grid chat-default-context-management-page__meta-grid${
                    maximizedPane !== 'none' ? ' chat-type-management-page__meta-grid--hidden' : ''
                  }`}
                >
                  <Form.Item
                    className="chat-type-management-page__meta-item chat-type-management-page__meta-item--name chat-default-context-management-page__meta-item--name"
                    label="공통 문맥명"
                    name="title"
                    rules={[{ required: true, message: '공통 문맥명을 입력하세요.' }]}
                  >
                    <Input placeholder="예: 모바일 검증 공통 규칙" />
                  </Form.Item>
                  <Form.Item
                    className="chat-type-management-page__meta-item chat-type-management-page__meta-item--enabled"
                    label="사용 여부"
                    name="enabled"
                    valuePropName="checked"
                  >
                    <Switch checkedChildren="사용" unCheckedChildren="중지" />
                  </Form.Item>
                </div>
                {isMobileViewport ? (
                  <Segmented
                    className="chat-type-management-page__mobile-toggle"
                    options={[
                      { label: '입력', value: 'edit' },
                      { label: '미리보기', value: 'preview' },
                    ]}
                    value={mobileView}
                    onChange={(value) => {
                      setMobileView(value as 'edit' | 'preview');
                      setMaximizedPane('none');
                    }}
                  />
                ) : null}
                <div
                  className={`chat-type-management-page__markdown-field${
                    isMobileViewport ? ' chat-type-management-page__markdown-field--mobile-active' : ''
                  }`}
                >
                  <Text strong className="chat-type-management-page__field-label">
                    공통 문맥 본문
                  </Text>
                  <div className="chat-type-management-page__markdown-editor">
                    <div className="chat-type-management-page__editor-toolbar">
                      {isMobileViewport ? null : (
                        <Space size={8} wrap>
                          <Button
                            className="chat-default-context-management-page__pane-toggle-button"
                            type={maximizedPane === 'edit' ? 'primary' : 'default'}
                            icon={maximizedPane === 'edit' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                            aria-label={maximizedPane === 'edit' ? '입력 축소' : '입력 최대화'}
                            title={maximizedPane === 'edit' ? '입력 축소' : '입력 최대화'}
                            onClick={() => {
                              setMaximizedPane((current) => (current === 'edit' ? 'none' : 'edit'));
                            }}
                          />
                          <Button
                            className="chat-default-context-management-page__pane-toggle-button"
                            type={maximizedPane === 'preview' ? 'primary' : 'default'}
                            icon={maximizedPane === 'preview' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                            aria-label={maximizedPane === 'preview' ? '미리보기 축소' : '미리보기 최대화'}
                            title={maximizedPane === 'preview' ? '미리보기 축소' : '미리보기 최대화'}
                            onClick={() => {
                              setMaximizedPane((current) => (current === 'preview' ? 'none' : 'preview'));
                            }}
                          />
                        </Space>
                      )}
                    </div>
                    <div
                      className={`chat-type-management-page__markdown-grid${
                        maximizedPane !== 'none' ? ' chat-type-management-page__markdown-grid--maximized' : ''
                      }`}
                    >
                      <div
                        className={`chat-type-management-page__markdown-pane${
                          isMobileViewport && mobileView === 'preview'
                            ? ' chat-type-management-page__markdown-pane--mobile-hidden'
                            : ''
                        }${
                          maximizedPane === 'preview' ? ' chat-type-management-page__markdown-pane--desktop-hidden' : ''
                        }`}
                      >
                        <div className="chat-type-management-page__markdown-pane-header">
                          <Text type="secondary">입력</Text>
                          {isMobileViewport ? (
                            <Button
                              size="small"
                              className="chat-default-context-management-page__pane-toggle-button"
                              type={maximizedPane === 'edit' ? 'primary' : 'default'}
                              icon={maximizedPane === 'edit' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                              aria-label={maximizedPane === 'edit' ? '입력 축소' : '입력 최대화'}
                              title={maximizedPane === 'edit' ? '입력 축소' : '입력 최대화'}
                              onClick={() => {
                                setMaximizedPane((current) => (current === 'edit' ? 'none' : 'edit'));
                              }}
                            />
                          ) : null}
                        </div>
                        <Form.Item name="content" noStyle>
                          <Input.TextArea
                            autoSize={isMobileViewport ? false : { minRows: 10, maxRows: 18 }}
                            className="chat-type-management-page__markdown-textarea"
                            placeholder={'## 적용 기준\n- 공통 문맥의 규칙을 Markdown으로 정의하세요.'}
                          />
                        </Form.Item>
                      </div>
                      <div
                        className={`chat-type-management-page__markdown-pane${
                          isMobileViewport && mobileView === 'edit'
                            ? ' chat-type-management-page__markdown-pane--mobile-hidden'
                            : ''
                        }${
                          maximizedPane === 'edit' ? ' chat-type-management-page__markdown-pane--desktop-hidden' : ''
                        }`}
                      >
                        <div className="chat-type-management-page__markdown-preview">
                          <div className="chat-type-management-page__markdown-pane-header">
                            <Text type="secondary">미리보기</Text>
                            {isMobileViewport ? (
                              <Button
                                size="small"
                                className="chat-default-context-management-page__pane-toggle-button"
                                type={maximizedPane === 'preview' ? 'primary' : 'default'}
                                icon={maximizedPane === 'preview' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                                aria-label={maximizedPane === 'preview' ? '미리보기 축소' : '미리보기 최대화'}
                                title={maximizedPane === 'preview' ? '미리보기 축소' : '미리보기 최대화'}
                                onClick={() => {
                                  setMaximizedPane((current) => (current === 'preview' ? 'none' : 'preview'));
                                }}
                              />
                            ) : null}
                          </div>
                          <div className="chat-type-management-page__markdown-preview-body">
                            <Form.Item noStyle shouldUpdate={(prev, next) => prev.content !== next.content}>
                              {({ getFieldValue }) => {
                                const content = String(getFieldValue('content') ?? '').trim();

                                return content ? (
                                  <MarkdownPreviewContent content={content} />
                                ) : (
                                  <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="미리보기할 공통 문맥 본문이 없습니다." />
                                );
                              }}
                            </Form.Item>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </Form>
          </div>
        </Card>
      )}
    </div>
  );
}
