import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import {
  Button,
  Card,
  Descriptions,
  Input,
  message,
  Modal,
  Segmented,
  Select,
  Space,
  Spin,
  Tag,
  Typography,
} from 'antd';
import {
  ArrowLeftOutlined,
  CopyOutlined,
  DiffOutlined,
  EditOutlined,
  HistoryOutlined,
  RobotOutlined,
  SendOutlined,
} from '@ant-design/icons';
import { useNavigate, useParams } from 'react-router-dom';
import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued';
import { customRequest } from 'helpers/http';
import { FlowRenderer } from './components/FlowRenderer';
import { DslView, type DslViewHandle } from './components/DslView';
import { RunWorkflowModal } from './components/RunWorkflowModal';
import type {
  Workflow,
  WorkflowDSL,
  WorkflowNodeType,
  WorkflowVersion,
} from './types';

const { Title } = Typography;

const STATUS_COLOR: Record<string, string> = {
  DRAFT: 'default',
  PUBLISHED: 'success',
};

const isDev = import.meta.env.DEV;

export default function WorkflowShowPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();

  const [workflow, setWorkflow] = useState<Workflow | null>(null);
  const [versions, setVersions] = useState<WorkflowVersion[]>([]);
  const [nodeTypes, setNodeTypes] = useState<WorkflowNodeType[]>([]);
  const [loading, setLoading] = useState(true);

  const [dsl, setDsl] = useState<WorkflowDSL | null>(null);
  const [currentVersion, setCurrentVersion] = useState<number | null>(null);
  const [viewMode, setViewMode] = useState<'canvas' | 'dsl'>('canvas');
  const dslViewRef = useRef<DslViewHandle>(null);

  // Publish modal state
  const [publishModalOpen, setPublishModalOpen] = useState(false);
  const [publishSummary, setPublishSummary] = useState('');
  const [publishLoading, setPublishLoading] = useState(false);

  // Diff modal state
  const [diffModalOpen, setDiffModalOpen] = useState(false);
  const [diffLeft, setDiffLeft] = useState<number | null>(null);
  const [diffRight, setDiffRight] = useState<number | null>(null);
  const [diffLeftDsl, setDiffLeftDsl] = useState<string>('');
  const [diffRightDsl, setDiffRightDsl] = useState<string>('');
  const [diffLoading, setDiffLoading] = useState(false);

  // Node detail panel
  const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);

  const nodeTypeMap = useMemo(() => {
    const map: Record<string, { category: string; icon: string }> = {};
    for (const nt of nodeTypes) {
      map[nt.type] = { category: nt.category, icon: nt.icon };
    }
    return map;
  }, [nodeTypes]);

  const selectedNode = useMemo(() => {
    if (!selectedNodeId || !dsl) return null;
    return dsl.nodes.find((n) => n.id === selectedNodeId) || null;
  }, [selectedNodeId, dsl]);

  useEffect(() => {
    customRequest<WorkflowNodeType[]>('workflow-node-types', 'GET')
      .then(setNodeTypes)
      .catch(() => {});
  }, []);

  useEffect(() => {
    if (!id) return;
    setLoading(true);
    Promise.all([
      customRequest<Workflow>(`workflow/${id}`, 'GET'),
      customRequest<WorkflowVersion[]>(`workflow/${id}/versions`, 'GET'),
    ])
      .then(([wf, vers]) => {
        setWorkflow(wf);
        setVersions(vers);
        const latestVersion = (wf as any).versions?.[0];
        if (latestVersion?.dsl) {
          setDsl(latestVersion.dsl);
          setCurrentVersion(latestVersion.version);
        }
      })
      .catch((e) => {
        message.error(e?.message ?? 'Failed to load workflow');
      })
      .finally(() => {
        setLoading(false);
      });
  }, [id]);

  const handleSelectVersion = useCallback(
    async (version: number) => {
      if (!id) return;
      try {
        const v = await customRequest<WorkflowVersion>(
          `workflow/${id}/versions/${version}`,
          'GET',
        );
        setDsl(v.dsl);
        setCurrentVersion(v.version);
      } catch (e: any) {
        message.error(e?.message ?? 'Failed to load version');
      }
    },
    [id],
  );

  const handleOpenDiff = useCallback(() => {
    if (versions.length < 2) {
      message.warning('至少需要两个版本才能对比');
      return;
    }
    // Default: compare latest two versions
    setDiffLeft(versions[1]?.version ?? null);
    setDiffRight(versions[0]?.version ?? null);
    setDiffLeftDsl('');
    setDiffRightDsl('');
    setDiffModalOpen(true);
  }, [versions]);

  const handleLoadDiff = useCallback(async () => {
    if (!id || diffLeft === null || diffRight === null) return;
    setDiffLoading(true);
    try {
      const [leftVer, rightVer] = await Promise.all([
        customRequest<WorkflowVersion>(
          `workflow/${id}/versions/${diffLeft}`,
          'GET',
        ),
        customRequest<WorkflowVersion>(
          `workflow/${id}/versions/${diffRight}`,
          'GET',
        ),
      ]);
      setDiffLeftDsl(JSON.stringify(leftVer.dsl, null, 2));
      setDiffRightDsl(JSON.stringify(rightVer.dsl, null, 2));
    } catch (e: any) {
      message.error(e?.message ?? 'Failed to load versions');
    } finally {
      setDiffLoading(false);
    }
  }, [id, diffLeft, diffRight]);

  useEffect(() => {
    if (diffModalOpen && diffLeft !== null && diffRight !== null) {
      handleLoadDiff();
    }
  }, [diffModalOpen, diffLeft, diffRight, handleLoadDiff]);

  const handlePublish = useCallback(async () => {
    if (!id) return;
    setPublishLoading(true);
    try {
      await customRequest(`workflow/${id}/publish`, 'POST', {
        changeSummary: publishSummary,
      });
      message.success('Workflow published successfully');
      setPublishModalOpen(false);
      setPublishSummary('');
      // Refresh data
      const [wf, vers] = await Promise.all([
        customRequest<Workflow>(`workflow/${id}`, 'GET'),
        customRequest<WorkflowVersion[]>(`workflow/${id}/versions`, 'GET'),
      ]);
      setWorkflow(wf);
      setVersions(vers);
    } catch (e: any) {
      message.error(e?.message ?? 'Failed to publish workflow');
    } finally {
      setPublishLoading(false);
    }
  }, [id, publishSummary]);

  const handleAiExplainDiff = useCallback(() => {
    if (!diffLeftDsl || !diffRightDsl) {
      message.warning('请先选择两个版本');
      return;
    }
    const prompt = `请对比以下两个版本的 Workflow DSL JSON，用中文解读主要变更内容（新增/删除/修改了哪些节点、连线、配置等）。

版本 v${diffLeft}（旧）:
\`\`\`json
${diffLeftDsl}
\`\`\`

版本 v${diffRight}（新）:
\`\`\`json
${diffRightDsl}
\`\`\`

请简洁地总结变更要点。`;
    const requestId = `diff_${Date.now()}_${Math.random().toString(36).slice(2)}`;
    window.parent.postMessage(
      { type: 'WORKFLOW_AGENT_REQUEST', requestId, prompt },
      '*',
    );
    message.success('已发送给 AI，请到右侧的Coding Agent对话窗口查看结果');
  }, [diffLeftDsl, diffRightDsl, diffLeft, diffRight]);

  if (loading) {
    return (
      <div
        style={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          height: '100vh',
        }}
      >
        <Spin size="large" />
      </div>
    );
  }

  return (
    <div
      style={{
        height: 'calc(100vh - 96px)',
        display: 'flex',
        flexDirection: 'column',
        background: '#f0f2f5',
        overflow: 'hidden',
      }}
    >
      {/* Header */}
      <Card style={{ marginBottom: 16, flexShrink: 0 }}>
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <Space>
            <Button
              type="text"
              icon={<ArrowLeftOutlined />}
              onClick={() => navigate('/admin/workflow')}
            ></Button>
            <Title level={4} style={{ margin: 0 }}>
              {workflow?.name || 'Workflow'}
            </Title>
            {workflow?.status && (
              <Tag color={STATUS_COLOR[workflow.status]}>{workflow.status}</Tag>
            )}
          </Space>
          <Space>
            {versions.length > 0 && (
              <Select
                value={currentVersion}
                onChange={handleSelectVersion}
                style={{ width: 200 }}
                placeholder="选择版本"
                options={versions.map((v) => ({
                  label: `v${v.version} - ${v.changeSummary?.slice(0, 20) || 'Saved'}`,
                  value: v.version,
                }))}
              />
            )}
            <Button
              icon={<DiffOutlined />}
              onClick={handleOpenDiff}
              disabled={versions.length < 2}
            >
              Diff
            </Button>
            {workflow?.status === 'DRAFT' && (
              <Button
                icon={<SendOutlined />}
                onClick={() => setPublishModalOpen(true)}
              >
                Publish
              </Button>
            )}
            {workflow?.status === 'PUBLISHED' && workflow?.isEnabled && (
              <RunWorkflowModal
                workflowId={id!}
                workflowName={workflow.name}
                onSuccess={(instanceId) =>
                  navigate(`/admin/workflow/instance/show/${instanceId}`)
                }
              />
            )}
            <Button
              icon={<HistoryOutlined />}
              onClick={() => navigate(`/admin/workflow/instances/show/${id}`)}
            >
              History
            </Button>
            <Button
              type="primary"
              icon={<EditOutlined />}
              onClick={() => navigate(`/admin/workflow/edit/${id}`)}
            >
              Edit
            </Button>
          </Space>
        </div>
      </Card>

      {/* View toggle row + DSL actions */}
      <div
        style={{
          marginBottom: 12,
          flexShrink: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
        }}
      >
        <Segmented
          value={viewMode}
          onChange={(v) => setViewMode(v as 'canvas' | 'dsl')}
          options={[
            { label: '画布', value: 'canvas' },
            { label: 'DSL', value: 'dsl' },
          ]}
        />
        {viewMode === 'dsl' && (
          <Button
            icon={<CopyOutlined />}
            onClick={() => dslViewRef.current?.copy()}
          >
            Copy
          </Button>
        )}
      </div>

      {/* Canvas + Node Detail Panel */}
      <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
        {viewMode === 'canvas' ? (
          <>
            <div style={{ flex: 1, position: 'relative' }}>
              <FlowRenderer
                dsl={dsl}
                nodeTypeMap={nodeTypeMap}
                selectedNodeId={selectedNodeId}
                readonly
                onNodeClick={(nodeId) => setSelectedNodeId(nodeId || null)}
              />
            </div>
            {selectedNode && (
              <div
                style={{
                  width: 320,
                  flexShrink: 0,
                  borderLeft: '1px solid #f0f0f0',
                  background: '#fff',
                  overflowY: 'auto',
                  padding: 16,
                }}
              >
                <Title level={5} style={{ marginTop: 0 }}>
                  {selectedNode.label}
                </Title>
                <Descriptions column={1} size="small" bordered>
                  <Descriptions.Item label="ID">
                    <Typography.Text copyable style={{ fontSize: 12 }}>
                      {selectedNode.id}
                    </Typography.Text>
                  </Descriptions.Item>
                  <Descriptions.Item label="类型">
                    {selectedNode.type}
                  </Descriptions.Item>
                  <Descriptions.Item label="分类">
                    <Tag>
                      {nodeTypeMap[selectedNode.type]?.category || 'ACTION'}
                    </Tag>
                  </Descriptions.Item>
                  {selectedNode.instanceRef && (
                    <Descriptions.Item label="节点实例">
                      {selectedNode.instanceRef.instanceName}
                    </Descriptions.Item>
                  )}
                </Descriptions>
                {selectedNode.config &&
                  Object.keys(selectedNode.config).length > 0 && (
                    <>
                      <Title level={5} style={{ marginTop: 16 }}>
                        配置
                      </Title>
                      <Descriptions column={1} size="small" bordered>
                        {Object.entries(selectedNode.config).map(
                          ([key, value]) => (
                            <Descriptions.Item key={key} label={key}>
                              {typeof value === 'object'
                                ? JSON.stringify(value, null, 2)
                                : String(value ?? '')}
                            </Descriptions.Item>
                          ),
                        )}
                      </Descriptions>
                    </>
                  )}
              </div>
            )}
          </>
        ) : (
          <DslView ref={dslViewRef} dsl={dsl} readonly />
        )}
      </div>

      {/* Diff Modal */}
      <Modal
        title="版本对比"
        open={diffModalOpen}
        onCancel={() => setDiffModalOpen(false)}
        footer={null}
        width="90vw"
        styles={{ body: { maxHeight: '70vh', overflow: 'auto' } }}
      >
        <Space style={{ marginBottom: 16 }}>
          <Select
            value={diffLeft}
            onChange={(v) => setDiffLeft(v)}
            style={{ width: 200 }}
            placeholder="选择左侧版本"
            options={versions.map((v) => ({
              label: `v${v.version} - ${v.changeSummary?.slice(0, 20) || 'Saved'}`,
              value: v.version,
            }))}
          />
          <span>vs</span>
          <Select
            value={diffRight}
            onChange={(v) => setDiffRight(v)}
            style={{ width: 200 }}
            placeholder="选择右侧版本"
            options={versions.map((v) => ({
              label: `v${v.version} - ${v.changeSummary?.slice(0, 20) || 'Saved'}`,
              value: v.version,
            }))}
          />
          {isDev && (
            <Button
              type="primary"
              icon={<RobotOutlined />}
              onClick={handleAiExplainDiff}
              disabled={!diffLeftDsl || !diffRightDsl}
            >
              AI 解读
            </Button>
          )}
        </Space>
        {diffLoading ? (
          <div style={{ textAlign: 'center', padding: 40 }}>
            <Spin size="large" />
          </div>
        ) : (
          <ReactDiffViewer
            oldValue={diffLeftDsl}
            newValue={diffRightDsl}
            splitView
            compareMethod={DiffMethod.LINES}
            leftTitle={`v${diffLeft}`}
            rightTitle={`v${diffRight}`}
          />
        )}
      </Modal>

      {/* Publish Modal */}
      <Modal
        title="Publish Workflow"
        open={publishModalOpen}
        onCancel={() => setPublishModalOpen(false)}
        onOk={handlePublish}
        confirmLoading={publishLoading}
        okText="Publish"
      >
        <Input.TextArea
          rows={3}
          placeholder="Version description (changeSummary)"
          value={publishSummary}
          onChange={(e) => setPublishSummary(e.target.value)}
        />
      </Modal>
    </div>
  );
}
