import { CheckCircleOutlined, CopyOutlined, LinkOutlined, PlusOutlined } from '@ant-design/icons';
import { Alert, App, Button, Card, Checkbox, Empty, Input, Result, Space, Steps, Tag, Typography } from 'antd';
import { useMemo, useState } from 'react';
import { useChatTypeRegistry } from './chatTypeAccess';
import { useTokenSettingRegistry, type TokenSettingRecord } from './tokenSettingAccess';
import { useTokenAccess } from './tokenAccess';
import { createManagedChatShareRoom, type ManagedChatShareRoom } from './mainChatPanel';
import { openExternalLinkInNewWindow } from './mainChatPanel/linkNavigation';
import { resolveChatPathForSession } from './chatSessionRouting';
import { copyTextToClipboard } from '../../utils/clipboard';
import './SharedChatManagementPage.css';

const { Paragraph, Text, Title } = Typography;

type SharedChatDraft = {
  tokenSettingId: string;
  chatTypeId: string;
  name: string;
  requestBadgeLabel: string;
  seedMessage: string;
  allowManageAccess: boolean;
};

const DEFAULT_DRAFT: SharedChatDraft = {
  tokenSettingId: '',
  chatTypeId: '',
  name: '',
  requestBadgeLabel: '',
  seedMessage: '이 공유채팅방에서 원하는 작업 내용을 남겨 주세요. 필요한 파일이나 참고 문맥이 있으면 함께 적어 주세요.',
  allowManageAccess: false,
};

function hasAllowedApp(setting: Pick<TokenSettingRecord, 'allowedAppIds'>, appId: string) {
  return setting.allowedAppIds.some((item) => item.trim().toLowerCase() === appId);
}

function resolveAbsoluteUrl(pathname: string) {
  if (typeof window === 'undefined') {
    return pathname;
  }

  try {
    return new URL(pathname, window.location.origin).toString();
  } catch {
    return pathname;
  }
}

export function SharedChatManagementPage() {
  const { message } = App.useApp();
  const { hasAccess } = useTokenAccess();
  const { tokenSettings, isLoading: isTokenSettingsLoading, errorMessage: tokenSettingsErrorMessage } = useTokenSettingRegistry();
  const { chatTypes, isLoading: isChatTypesLoading, errorMessage: chatTypesErrorMessage } = useChatTypeRegistry();
  const [currentStep, setCurrentStep] = useState(0);
  const [draft, setDraft] = useState<SharedChatDraft>(DEFAULT_DRAFT);
  const [createErrorMessage, setCreateErrorMessage] = useState('');
  const [isCreating, setIsCreating] = useState(false);
  const [createdRoom, setCreatedRoom] = useState<(ManagedChatShareRoom & { shareUrl: string; conversationUrl: string }) | null>(null);

  const availableTokenSettings = useMemo(
    () => tokenSettings.filter((item) => item.enabled && hasAllowedApp(item, 'chat-live')),
    [tokenSettings],
  );
  const availableChatTypes = useMemo(() => chatTypes.filter((item) => item.enabled), [chatTypes]);
  const selectedTokenSetting = useMemo(
    () => availableTokenSettings.find((item) => item.id === draft.tokenSettingId) ?? null,
    [availableTokenSettings, draft.tokenSettingId],
  );
  const selectedChatType = useMemo(
    () => availableChatTypes.find((item) => item.id === draft.chatTypeId) ?? null,
    [availableChatTypes, draft.chatTypeId],
  );
  const canGrantManageAccess = useMemo(
    () =>
      Boolean(
        selectedTokenSetting &&
          (hasAllowedApp(selectedTokenSetting, 'chat-room-settings') ||
            hasAllowedApp(selectedTokenSetting, 'token-setting') ||
            hasAllowedApp(selectedTokenSetting, 'shared-resource') ||
            hasAllowedApp(selectedTokenSetting, 'server-command')),
      ),
    [selectedTokenSetting],
  );
  const suggestedShareName = useMemo(
    () => (selectedChatType ? `${selectedChatType.name} 공유채팅` : ''),
    [selectedChatType],
  );

  const stepItems = [
    { title: '공유 토큰' },
    { title: '채팅 유형' },
    { title: '채팅방 정보' },
    { title: 'URL 공유' },
  ];
  const openManagedShareWindow = (url: string) => {
    openExternalLinkInNewWindow(url, {
      onUnsupportedStandalone: (fallbackUrl) => {
        void copyTextToClipboard(fallbackUrl)
          .then(() => {
            message.info('현재 모바일 PWA에서는 preview 앱 열기도 막혀 URL을 복사했습니다. 브라우저에서 붙여 열어 주세요.');
          })
          .catch(() => {
            message.info('현재 모바일 PWA에서는 새 창과 preview 앱 열기가 막힐 수 있습니다. URL 복사 후 브라우저에서 열어 주세요.');
          });
      },
    });
  };

  const handleMoveNext = () => {
    if (currentStep === 0 && !selectedTokenSetting) {
      message.warning('공유 토큰 설정을 먼저 선택하세요.');
      return;
    }

    if (currentStep === 1 && !selectedChatType) {
      message.warning('채팅 유형을 먼저 선택하세요.');
      return;
    }

    if (currentStep === 2) {
      if (!draft.name.trim()) {
        message.warning('공유 이름을 입력하세요.');
        return;
      }

      if (!draft.seedMessage.trim()) {
        message.warning('공유 시작 문구를 입력하세요.');
        return;
      }

    }

    setCurrentStep((previous) => Math.min(previous + 1, stepItems.length - 1));
  };

  const handleCreateRoom = async () => {
    if (!selectedTokenSetting || !selectedChatType) {
      message.warning('공유 토큰과 채팅 유형을 먼저 선택하세요.');
      return;
    }

    const name = draft.name.trim();
    const seedMessage = draft.seedMessage.trim();

    if (!name || !seedMessage) {
      message.warning('공유 이름과 공유 시작 문구를 입력하세요.');
      return;
    }

    setIsCreating(true);
    setCreateErrorMessage('');

    try {
      const created = await createManagedChatShareRoom({
        tokenSettingId: selectedTokenSetting.id,
        chatTypeId: selectedChatType.id,
        chatTypeLabel: selectedChatType.name,
        name,
        requestBadgeLabel: draft.requestBadgeLabel.trim() || null,
        seedMessage,
        allowManageAccess: draft.allowManageAccess && canGrantManageAccess,
      });
      const shareUrl = resolveAbsoluteUrl(created.sharePath);
      const conversationUrl = resolveAbsoluteUrl(`${resolveChatPathForSession(created.sessionId)}?sessionId=${encodeURIComponent(created.sessionId)}`);
      setCreatedRoom({
        ...created,
        shareUrl,
        conversationUrl,
      });
      setCurrentStep(3);
      message.success('공유채팅방을 생성했습니다.');
    } catch (error) {
      setCreateErrorMessage(error instanceof Error ? error.message : '공유채팅방 생성에 실패했습니다.');
    } finally {
      setIsCreating(false);
    }
  };

  const handleReset = () => {
    setDraft(DEFAULT_DRAFT);
    setCurrentStep(0);
    setCreateErrorMessage('');
    setCreatedRoom(null);
  };

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

  return (
    <div className="shared-chat-management-page">
      <Card
        title="공유채팅 생성"
        className="shared-chat-management-page__card"
        extra={
          createdRoom ? (
            <Button icon={<PlusOutlined />} onClick={handleReset}>
              새로 만들기
            </Button>
          ) : null
        }
      >
        <div className="shared-chat-management-page__layout">
          <div className="shared-chat-management-page__steps">
            <Steps current={currentStep} items={stepItems} responsive={false} />
          </div>
          <div className="shared-chat-management-page__content">
            <div className="shared-chat-management-page__stage">
              {tokenSettingsErrorMessage ? <Alert showIcon type="error" message={tokenSettingsErrorMessage} /> : null}
              {chatTypesErrorMessage ? <Alert showIcon type="error" message={chatTypesErrorMessage} /> : null}
              {createErrorMessage ? <Alert showIcon type="error" message={createErrorMessage} /> : null}

              <div className="shared-chat-management-page__stage-body">
                {currentStep === 0 ? (
                  <Card bordered={false} className="shared-chat-management-page__panel">
                    <Title level={5}>1. 공유 토큰 설정 선택</Title>
                    <Paragraph type="secondary">
                      `chat-live` 권한이 있는 토큰 설정만 표시합니다. 이 설정이 공유 URL의 만료 시간과 사용량 한도를 결정합니다.
                    </Paragraph>
                    {availableTokenSettings.length > 0 ? (
                      <div className="shared-chat-management-page__option-list">
                        {availableTokenSettings.map((item) => {
                          const active = item.id === draft.tokenSettingId;
                          return (
                            <button
                              key={item.id}
                              type="button"
                              className={`shared-chat-management-page__option-card${active ? ' shared-chat-management-page__option-card--active' : ''}`}
                              onClick={() => {
                                setDraft((previous) => ({
                                  ...previous,
                                  tokenSettingId: item.id,
                                  allowManageAccess:
                                    previous.allowManageAccess &&
                                    (hasAllowedApp(item, 'chat-room-settings') ||
                                      hasAllowedApp(item, 'token-setting') ||
                                      hasAllowedApp(item, 'shared-resource') ||
                                      hasAllowedApp(item, 'server-command')),
                                }));
                              }}
                            >
                              <div className="shared-chat-management-page__option-head">
                                <Space size={[8, 8]} wrap>
                                  <Text strong>{item.name}</Text>
                                  <Tag>{item.id}</Tag>
                                  <Tag color="blue">{`기본 ${item.defaultExpiresInMinutes > 0 ? `${item.defaultExpiresInMinutes}분` : '무제한'}`}</Tag>
                                </Space>
                              </div>
                              <Text type="secondary">{item.description || '설명 없음'}</Text>
                              <div className="shared-chat-management-page__tag-row">
                                {item.allowedAppIds.map((appId) => (
                                  <Tag key={`${item.id}-${appId}`}>{appId}</Tag>
                                ))}
                              </div>
                            </button>
                          );
                        })}
                      </div>
                    ) : (
                      <Empty
                        description={
                          isTokenSettingsLoading ? '공유 토큰 설정을 불러오는 중입니다.' : '공유채팅에 사용할 토큰 설정이 없습니다.'
                        }
                      />
                    )}
                  </Card>
                ) : null}

                {currentStep === 1 ? (
                  <Card bordered={false} className="shared-chat-management-page__panel">
                    <Title level={5}>2. 채팅 유형 선택</Title>
                    <Paragraph type="secondary">
                      공유 URL에 들어온 사용자는 이 채팅 유형 기준으로 대화를 이어갑니다.
                    </Paragraph>
                    {availableChatTypes.length > 0 ? (
                      <div className="shared-chat-management-page__option-list">
                        {availableChatTypes.map((item) => {
                          const active = item.id === draft.chatTypeId;
                          return (
                            <button
                              key={item.id}
                              type="button"
                              className={`shared-chat-management-page__option-card${active ? ' shared-chat-management-page__option-card--active' : ''}`}
                              onClick={() => {
                                setDraft((previous) => ({
                                  ...previous,
                                  chatTypeId: item.id,
                                }));
                              }}
                            >
                              <div className="shared-chat-management-page__option-head">
                                <Space size={[8, 8]} wrap>
                                  <Text strong>{item.name}</Text>
                                  <Tag>{item.id}</Tag>
                                </Space>
                              </div>
                              <Text type="secondary">{item.description || '설명 없음'}</Text>
                              <div className="shared-chat-management-page__tag-row">
                                {item.permissions.map((permission) => (
                                  <Tag key={`${item.id}-${permission}`}>{permission}</Tag>
                                ))}
                              </div>
                            </button>
                          );
                        })}
                      </div>
                    ) : (
                      <Empty description={isChatTypesLoading ? '채팅 유형을 불러오는 중입니다.' : '사용 가능한 채팅 유형이 없습니다.'} />
                    )}
                  </Card>
                ) : null}

                {currentStep === 2 ? (
                  <Card bordered={false} className="shared-chat-management-page__panel">
                    <Title level={5}>3. 채팅방 정보 입력</Title>
                    <div className="shared-chat-management-page__field-grid">
                      <label className="shared-chat-management-page__field">
                        <span>공유 이름</span>
                        <Input
                          value={draft.name}
                          maxLength={160}
                          placeholder={suggestedShareName || '예: 공유 문구 검토방'}
                          onChange={(event) => setDraft((previous) => ({ ...previous, name: event.target.value }))}
                        />
                      </label>
                      <label className="shared-chat-management-page__field">
                        <span>채팅 유형</span>
                        <Input value={selectedChatType?.name ?? ''} readOnly />
                      </label>
                      <label className="shared-chat-management-page__field">
                        <span>요청 뱃지</span>
                        <Input
                          value={draft.requestBadgeLabel}
                          maxLength={120}
                          placeholder="선택 입력"
                          onChange={(event) => setDraft((previous) => ({ ...previous, requestBadgeLabel: event.target.value }))}
                        />
                      </label>
                      <label className="shared-chat-management-page__field shared-chat-management-page__field--full">
                        <span>공유 시작 문구</span>
                        <Input.TextArea
                          rows={6}
                          value={draft.seedMessage}
                          placeholder="공유채팅방에 처음 보일 안내나 첫 질문을 입력하세요."
                          onChange={(event) => setDraft((previous) => ({ ...previous, seedMessage: event.target.value }))}
                        />
                      </label>
                    </div>
                    <div className="shared-chat-management-page__checkbox-row">
                      <Checkbox
                        checked={draft.allowManageAccess && canGrantManageAccess}
                        disabled={!canGrantManageAccess}
                        onChange={(event) => setDraft((previous) => ({ ...previous, allowManageAccess: event.target.checked }))}
                      >
                        공유 참여자에게 관리 권한 허용
                      </Checkbox>
                      <Text type="secondary">
                        {canGrantManageAccess
                          ? '선택 시 채팅방 설정 또는 연결된 관리 화면 접근이 열립니다.'
                          : '선택한 토큰 설정에는 노출 가능한 관리 앱 권한이 없습니다.'}
                      </Text>
                    </div>
                    <div className="shared-chat-management-page__summary">
                      <div>
                        <Text type="secondary">공유 토큰</Text>
                        <div className="shared-chat-management-page__summary-value">{selectedTokenSetting?.name ?? '-'}</div>
                      </div>
                      <div>
                        <Text type="secondary">생성 이름</Text>
                        <div className="shared-chat-management-page__summary-value">{draft.name.trim() || '-'}</div>
                      </div>
                      <div>
                        <Text type="secondary">유효 시간</Text>
                        <div className="shared-chat-management-page__summary-value">
                          {selectedTokenSetting
                            ? selectedTokenSetting.defaultExpiresInMinutes > 0
                              ? `${selectedTokenSetting.defaultExpiresInMinutes}분`
                              : '무제한'
                          : '-'}
                        </div>
                      </div>
                      <div>
                        <Text type="secondary">접근 보호</Text>
                        <div className="shared-chat-management-page__summary-value">
                          공유받은 사용자가 필요할 때 채팅방 설정에서 직접 설정
                        </div>
                      </div>
                    </div>
                  </Card>
                ) : null}

                {currentStep === 3 ? (
                  <Card bordered={false} className="shared-chat-management-page__panel">
                    {createdRoom ? (
                      <Result
                        status="success"
                        icon={<CheckCircleOutlined />}
                        title="공유채팅방 URL이 준비되었습니다."
                        subTitle="이 URL로 외부 사용자가 같은 채팅방 흐름에 이어서 질문할 수 있습니다."
                        extra={
                          <Space wrap>
                            <Button
                              type="primary"
                              icon={<CopyOutlined />}
                              onClick={async () => {
                                await copyTextToClipboard(createdRoom.shareUrl);
                                message.success('공유 URL을 복사했습니다.');
                              }}
                            >
                              URL 복사
                            </Button>
                            <Button
                              icon={<LinkOutlined />}
                              onClick={() => {
                                openManagedShareWindow(createdRoom.shareUrl);
                              }}
                            >
                              공유 화면 열기
                            </Button>
                            <Button
                              onClick={() => {
                                openManagedShareWindow(createdRoom.conversationUrl);
                              }}
                            >
                              내부 채팅방 열기
                            </Button>
                          </Space>
                        }
                      />
                    ) : (
                      <Alert showIcon type="info" message="생성된 공유채팅방이 없습니다. 이전 단계에서 생성을 완료하세요." />
                    )}
                    {createdRoom ? (
                      <div className="shared-chat-management-page__result-grid">
                        <label className="shared-chat-management-page__field shared-chat-management-page__field--full">
                          <span>공유 이름</span>
                          <Input value={createdRoom.name} readOnly />
                        </label>
                        <label className="shared-chat-management-page__field shared-chat-management-page__field--full">
                          <span>공유 URL</span>
                          <Input value={createdRoom.shareUrl} readOnly />
                        </label>
                        <label className="shared-chat-management-page__field shared-chat-management-page__field--full">
                          <span>내부 채팅방</span>
                          <Input value={createdRoom.conversationUrl} readOnly />
                        </label>
                        <div className="shared-chat-management-page__field shared-chat-management-page__field--full">
                          <span>적용 권한</span>
                          <div className="shared-chat-management-page__tag-row">
                            {createdRoom.permissions.map((permission) => (
                              <Tag key={permission}>{permission}</Tag>
                            ))}
                          </div>
                        </div>
                        <label className="shared-chat-management-page__field">
                          <span>접근 보호</span>
                          <Input value="공유 후 채팅방 설정에서 변경" readOnly />
                        </label>
                      </div>
                    ) : null}
                  </Card>
                ) : null}
              </div>
            </div>

            <div className="shared-chat-management-page__actions">
              <Button onClick={() => setCurrentStep((previous) => Math.max(previous - 1, 0))} disabled={currentStep === 0 || isCreating}>
                이전
              </Button>
              {currentStep < 2 ? (
                <Button type="primary" onClick={handleMoveNext}>
                  다음
                </Button>
              ) : currentStep === 2 ? (
                <Button type="primary" loading={isCreating} onClick={() => void handleCreateRoom()}>
                  공유채팅 생성
                </Button>
              ) : null}
            </div>
          </div>
        </div>
      </Card>
    </div>
  );
}
