import React, { useEffect, useRef, useState } from 'react';
import {
  XCard,
  registerCatalog,
  type ActionPayload,
  type XAgentCommand_v0_9,
} from '@ant-design/x-card';
import {
  Alert,
  Button,
  Flex,
  Popconfirm,
  Steps,
  Table,
  Tag,
  Typography,
  type TableProps,
} from 'antd';
import type { AiReviewRow, AiReviewSchema, AiReviewSection, AiReviewSectionType } from './types';
import { useXCardSurface } from './useSubmissionState';
import {
  GROUP_STATUS_LABELS,
  SECTION_ORDER,
  SECTION_STATUS_LABELS,
  SECTION_TYPE_LABELS,
  dependencyHint,
  groupSections,
  groupStatus,
  sectionCount,
  sectionResultText,
  sectionStatus,
  sectionType,
} from './reviewSection';

const REVIEW_CATALOG_ID = 'gongxue-review-catalog';

registerCatalog({
  catalogId: REVIEW_CATALOG_ID,
  components: {
    ReviewPreview: {
      type: 'object',
      properties: {
        review: { type: 'object' },
        disabled: { type: 'boolean' },
        activeKey: { type: 'string' },
        activeType: { type: 'string' },
        submittingKey: { type: ['string', 'null'] },
        submittingGroup: { type: 'boolean' },
        error: { type: ['string', 'null'] },
      },
    },
  },
});

function surfaceId(reviewId: string): string {
  return `review-${reviewId}`;
}

function errorMessage(reason: unknown): string {
  if (reason instanceof Error) return reason.message;
  if (reason && typeof reason === 'object' && 'message' in reason) {
    return String((reason as { message?: unknown }).message ?? '确认失败，请稍后重试');
  }
  return '确认失败，请稍后重试';
}

function SectionTable({ section }: { section: AiReviewSection }) {
  const columns: TableProps<AiReviewRow>['columns'] = section.columns.map((column) => ({
    title: column.title,
    dataIndex: column.key,
    key: column.key,
    ellipsis: true,
    render: (value: unknown) =>
      value === null || value === undefined || value === '' ? (
        <Typography.Text type="secondary">-</Typography.Text>
      ) : (
        String(value)
      ),
  }));
  return (
    <Table<AiReviewRow>
      size="small"
      rowKey="__rowKey"
      columns={columns}
      dataSource={section.rows.map((row, index) => ({ ...row, __rowKey: `row-${index}` }))}
      pagination={{ pageSize: 10, size: 'small', hideOnSinglePage: true }}
      scroll={{ x: 'max-content' }}
    />
  );
}

interface ReviewPreviewProps {
  review?: AiReviewSchema & {
    submitting?: boolean;
    activeKey?: string;
    activeType?: AiReviewSectionType;
    submittingKey?: string | null;
    submittingGroup?: boolean;
    error?: string | null;
  };
  disabled?: boolean;
  onAction?: (name: string, context: Record<string, unknown>) => void;
}

const ReviewPreview: React.FC<ReviewPreviewProps> = ({ review, disabled, onAction }) => {
  if (!review) return null;
  const submitted = review.status === 'submitted';
  const expired = review.status === 'expired';
  const submitting = Boolean(review.submitting);
  const submittingKey = review.submittingKey ?? null;
  const submittingGroup = Boolean(review.submittingGroup);
  const sections = review.sections;
  const presentTypes = SECTION_ORDER.filter((type) =>
    sections.some((section) => sectionType(section) === type),
  );
  const activeType = presentTypes.includes(review.activeType as AiReviewSectionType)
    ? (review.activeType as AiReviewSectionType)
    : presentTypes[0];
  if (!activeType) return null;
  const activeSection =
    sections.find((section) => section.key === review.activeKey) ??
    groupSections(sections, activeType)[0];
  const activeStatus = activeSection ? sectionStatus(activeSection) : 'pending';
  const dependency =
    activeSection === undefined ? null : dependencyHint(sections, sectionType(activeSection));
  const typeItems = presentTypes.map((type, index) => {
    const items = groupSections(sections, type);
    const status = groupStatus(sections, type, submittingKey, submittingGroup, activeType);
    const stepStatus: 'finish' | 'error' | 'process' | 'wait' =
      status === 'submitted'
        ? 'finish'
        : status === 'failed'
          ? 'error'
          : status === 'importing' || type === activeType
            ? 'process'
            : 'wait';
    return {
      key: type,
      title: `${SECTION_TYPE_LABELS[type]}（${items.reduce((sum, item) => sum + sectionCount(item), 0)}）`,
      content: GROUP_STATUS_LABELS[status],
      status: stepStatus,
      index,
    };
  });
  const group = groupSections(sections, activeType);
  const typeTotal = group.reduce((sum, section) => sum + sectionCount(section), 0);
  const groupDep = dependencyHint(sections, activeType);
  const groupReady =
    !submitted &&
    !expired &&
    !disabled &&
    !submitting &&
    !submittingKey &&
    !submittingGroup &&
    group.length > 0 &&
    !group.every((section) => sectionStatus(section) === 'submitted') &&
    !groupDep;
  const anyRunning = submitting || Boolean(submittingKey) || submittingGroup;
  const allIssues = sections.flatMap((section) => section.issues);
  const allRows = sections.reduce((sum, section) => sum + sectionCount(section), 0);

  return (
    <div className="ai-chat-review-card">
      <Flex justify="space-between" align="center" wrap gap={8}>
        <Typography.Text strong className="ai-chat-review-card__title">
          {review.title}
        </Typography.Text>
        {submitted ? (
          <Tag color="success">已导入</Tag>
        ) : expired ? (
          <Tag>已失效</Tag>
        ) : anyRunning ? (
          <Tag color="processing">导入中</Tag>
        ) : (
          <Tag color="gold">待确认</Tag>
        )}
      </Flex>
      {review.summary && (
        <Typography.Paragraph type="secondary" className="ai-chat-review-card__summary">
          {review.summary}
        </Typography.Paragraph>
      )}
      {expired && (
        <Alert
          type="warning"
          showIcon
          title="此导入预览已被新的预览替代，已失效"
          description="如需导入，请使用最新的预览卡。"
        />
      )}
      <Steps
        size="small"
        current={Math.max(
          0,
          typeItems.findIndex((item) => item.key === activeType),
        )}
        items={typeItems.map((item) => ({
          key: item.key,
          title: item.title,
          content: item.content,
          status: item.status,
        }))}
        onChange={(index) => {
          const type = typeItems[index]?.key;
          if (type) onAction?.('review:selectType', { type });
        }}
      />
      {activeType && (
        <Flex vertical gap={8} className="ai-chat-review-card__group">
          <Flex justify="space-between" align="center" wrap gap={8}>
            <Flex vertical gap={2}>
              <Typography.Text strong>
                {SECTION_TYPE_LABELS[activeType]} · 共 {group.length} 张表 / {typeTotal} 行
              </Typography.Text>
              <Typography.Text type="secondary">
                {
                  GROUP_STATUS_LABELS[
                    groupStatus(sections, activeType, submittingKey, submittingGroup, activeType)
                  ]
                }
              </Typography.Text>
            </Flex>
            {groupDep && (
              <Alert
                type="warning"
                showIcon
                title={
                  groupDep.step === -1
                    ? `「${groupDep.title}」分表尚未生成或导入，请先确认前置步骤`
                    : `请先确认第 ${groupDep.step + 1} 步「${groupDep.title}」`
                }
              />
            )}
            {!submitted && !expired && group.length > 0 && (
              <Popconfirm
                title={`确认导入本组 ${group.length} 张表？`}
                description={`本组共 ${typeTotal} 行，确认后将按顺序逐表导入。`}
                okText="确认导入"
                cancelText="取消"
                disabled={!groupReady}
                onConfirm={() =>
                  onAction?.('review:confirmGroup', {
                    reviewId: review.id,
                    type: activeType,
                  })
                }
              >
                <Button type="primary" loading={submittingGroup} disabled={!groupReady}>
                  {groupStatus(sections, activeType, submittingKey, submittingGroup, activeType) ===
                  'submitted'
                    ? '已导入'
                    : `确认本组 ${group.length} 张表`}
                </Button>
              </Popconfirm>
            )}
          </Flex>
          <Flex vertical gap={8} className="ai-chat-review-card__sheets">
            {group.map((section, index) => {
              const status = sectionStatus(section);
              const dep = dependencyHint(sections, sectionType(section));
              const canConfirm =
                !submitted &&
                !expired &&
                !disabled &&
                !anyRunning &&
                status !== 'submitted' &&
                status !== 'skipped' &&
                !dep;
              return (
                <Flex
                  key={section.key}
                  justify="space-between"
                  align="center"
                  wrap
                  gap={8}
                  className="ai-chat-review-card__sheet"
                  onClick={() => onAction?.('review:selectStep', { sectionKey: section.key })}
                >
                  <Flex vertical gap={2} style={{ minWidth: 160 }}>
                    <Typography.Text>
                      {index + 1}. {section.title}
                      {section.sheet ? (
                        <Typography.Text type="secondary">（{section.sheet}）</Typography.Text>
                      ) : null}
                    </Typography.Text>
                    <Typography.Text type="secondary">
                      {sectionCount(section)} 行 · {SECTION_STATUS_LABELS[status]}
                    </Typography.Text>
                  </Flex>
                  <Button
                    size="small"
                    loading={submittingKey === section.key}
                    disabled={!canConfirm}
                    onClick={(event) => {
                      event.stopPropagation();
                      onAction?.('review:confirmStep', {
                        reviewId: review.id,
                        sectionKey: section.key,
                      });
                    }}
                  >
                    {status === 'failed'
                      ? '重试导入本步'
                      : status === 'submitted'
                        ? '已导入'
                        : status === 'skipped'
                          ? '已跳过'
                          : expired
                            ? '已失效'
                            : '确认导入本步'}
                  </Button>
                </Flex>
              );
            })}
          </Flex>
          {activeSection && (
            <Flex vertical gap={8} className="ai-chat-review-card__step">
              {activeSection.issues.length > 0 && (
                <Alert
                  type="warning"
                  showIcon
                  title={`${activeSection.title}：${activeSection.issues.length} 条待处理`}
                  description={
                    <ul className="ai-chat-review__issues">
                      {activeSection.issues.slice(0, 20).map((issue, issueIndex) => (
                        <li key={issueIndex}>{issue}</li>
                      ))}
                    </ul>
                  }
                />
              )}
              <SectionTable section={activeSection} />
              {dependency && (
                <Alert
                  type="warning"
                  showIcon
                  title={
                    dependency.step === -1
                      ? `「${dependency.title}」分表尚未生成或导入，请先确认前置步骤`
                      : `请先确认第 ${dependency.step + 1} 步「${dependency.title}」`
                  }
                />
              )}
              {activeStatus === 'failed' && (
                <Alert type="error" showIcon title="本步导入失败，可重试" />
              )}
              {activeSection.resultSummary && activeStatus === 'submitted' && (
                <Typography.Text type="secondary" className="ai-chat-review-card__step-result">
                  {sectionResultText(activeSection)}
                </Typography.Text>
              )}
            </Flex>
          )}
        </Flex>
      )}
      <Flex
        justify="space-between"
        align="center"
        wrap
        gap={8}
        className="ai-chat-review-card__footer"
      >
        <Typography.Text type="secondary">
          共 {allRows} 行，含 {allIssues.length} 条提示
        </Typography.Text>
        {!submitted && !expired && (
          <Popconfirm
            title={`确认导入全部 ${sections.length} 张表？`}
            description={`全部共 ${allRows} 行，将按类型与依赖顺序逐表导入。`}
            okText="确认导入"
            cancelText="取消"
            disabled={submitting || anyRunning || disabled}
            onConfirm={() => onAction?.('review:submit', { reviewId: review.id })}
          >
            <Button type="primary" loading={submitting} disabled={disabled || anyRunning}>
              全部确认并入库
            </Button>
          </Popconfirm>
        )}
      </Flex>
      {submitted && <Alert type="success" showIcon title="已确认导入，数据已入库" />}
      {review.error && (
        <Alert
          type="error"
          showIcon
          title={review.error}
          className="ai-chat-review-card__step-error"
        />
      )}
    </div>
  );
};

export interface DynamicReviewProps {
  review: AiReviewSchema;
  disabled?: boolean;
  messageId?: number;
  onSubmit: (reviewId: string) => void | Promise<void>;
  onConfirmStep?: (
    messageId: number | undefined,
    reviewId: string,
    sectionKey: string,
  ) => AiReviewSchema | Promise<AiReviewSchema> | void;
  onConfirmGroup?: (
    messageId: number | undefined,
    reviewId: string,
    type: AiReviewSectionType,
  ) => AiReviewSchema | Promise<AiReviewSchema> | void;
}

/**
 * Batch-import review card rendered through the official A2UI renderer
 * (@ant-design/x-card). Sections are grouped by business type; each sheet is
 * confirmed independently, the whole type group can be confirmed together, or
 * everything can be confirmed in one flow.
 */
export const DynamicReview: React.FC<DynamicReviewProps> = ({
  review,
  disabled,
  messageId,
  onSubmit,
  onConfirmStep,
  onConfirmGroup,
}) => {
  const [submitting, setSubmitting] = useState(false);
  const [submittingKey, setSubmittingKey] = useState<string | null>(null);
  const [submittingGroup, setSubmittingGroup] = useState(false);
  const [activeKey, setActiveKey] = useState<string | undefined>(undefined);
  const [activeType, setActiveType] = useState<AiReviewSectionType | undefined>(undefined);
  const activeTypeRef = useRef<AiReviewSectionType | undefined>(activeType);
  activeTypeRef.current = activeType;
  const [localReview, setLocalReview] = useState<AiReviewSchema>(review);
  const [error, setError] = useState<string | null>(null);
  const sid = surfaceId(localReview.id);
  const { commands, pushCommands } = useXCardSurface(sid);

  useEffect(() => {
    setLocalReview(review);
    const types = SECTION_ORDER.filter((type) =>
      review.sections.some((section) => sectionType(section) === type),
    );
    const preferredType =
      activeTypeRef.current && types.includes(activeTypeRef.current)
        ? activeTypeRef.current
        : types[0];
    setActiveType(preferredType);
    setActiveKey((current) =>
      current &&
      review.sections.some(
        (section) => section.key === current && sectionType(section) === preferredType,
      )
        ? current
        : review.sections.find((section) => sectionType(section) === preferredType)?.key,
    );
  }, [review]);

  useEffect(() => {
    const cmds: XAgentCommand_v0_9[] = [
      {
        version: 'v0.9',
        createSurface: { surfaceId: sid, catalogId: REVIEW_CATALOG_ID },
      },
      {
        version: 'v0.9',
        updateDataModel: {
          surfaceId: sid,
          path: '/review',
          value: {
            ...localReview,
            submitting,
            activeKey,
            activeType,
            submittingKey,
            submittingGroup,
            error,
          },
        },
      },
      {
        version: 'v0.9',
        updateComponents: {
          surfaceId: sid,
          components: [
            {
              id: 'root',
              component: 'ReviewPreview',
              review: { path: '/review' },
              disabled: Boolean(disabled),
            },
          ],
        },
      },
    ];
    pushCommands(cmds);
  }, [
    activeKey,
    activeType,
    disabled,
    error,
    localReview,
    pushCommands,
    sid,
    submitting,
    submittingGroup,
    submittingKey,
  ]);

  const handleSubmit = async (reviewId: string) => {
    if (submitting) return;
    setSubmitting(true);
    setError(null);
    try {
      await onSubmit(reviewId);
    } catch (reason) {
      setError(errorMessage(reason));
    } finally {
      setSubmitting(false);
    }
  };

  const handleConfirmStep = async (reviewId: string, sectionKey: string) => {
    if (submittingKey) return;
    setSubmittingKey(sectionKey);
    setError(null);
    try {
      const updated = await onConfirmStep?.(messageId, reviewId, sectionKey);
      if (updated) setLocalReview(updated);
    } catch (reason) {
      setError(errorMessage(reason));
    } finally {
      setSubmittingKey(null);
    }
  };

  const handleConfirmGroup = async (reviewId: string, type: AiReviewSectionType) => {
    if (submittingGroup) return;
    setSubmittingGroup(true);
    setError(null);
    try {
      const updated = await onConfirmGroup?.(messageId, reviewId, type);
      if (updated) setLocalReview(updated);
    } catch (reason) {
      setError(errorMessage(reason));
    } finally {
      setSubmittingGroup(false);
    }
  };

  const handleAction = (payload: ActionPayload) => {
    const context = payload.context ?? {};
    if (payload.name === 'review:submit') {
      const reviewId = typeof context.reviewId === 'string' ? context.reviewId : localReview.id;
      void handleSubmit(reviewId);
      return;
    }
    if (payload.name === 'review:selectType') {
      const type = context.type as AiReviewSectionType | undefined;
      if (type && SECTION_ORDER.includes(type)) {
        setActiveType(type);
        setActiveKey(localReview.sections.find((section) => sectionType(section) === type)?.key);
      }
      return;
    }
    if (payload.name === 'review:selectStep') {
      if (typeof context.sectionKey === 'string') {
        const section = localReview.sections.find((item) => item.key === context.sectionKey);
        setActiveKey(context.sectionKey);
        if (section) setActiveType(sectionType(section));
      }
      return;
    }
    if (payload.name === 'review:confirmStep') {
      const reviewId = typeof context.reviewId === 'string' ? context.reviewId : localReview.id;
      if (typeof context.sectionKey === 'string') {
        void handleConfirmStep(reviewId, context.sectionKey);
      }
      return;
    }
    if (payload.name === 'review:confirmGroup') {
      const reviewId = typeof context.reviewId === 'string' ? context.reviewId : localReview.id;
      const type = context.type as AiReviewSectionType | undefined;
      if (type && SECTION_ORDER.includes(type)) {
        void handleConfirmGroup(reviewId, type);
      }
    }
  };

  return (
    <div className="ai-chat-review">
      <XCard.Box components={{ ReviewPreview }} commands={commands} onAction={handleAction}>
        <XCard.Card id={surfaceId(localReview.id)} />
      </XCard.Box>
      {error && <Alert type="error" showIcon title={error} className="ai-chat-review__error" />}
    </div>
  );
};
