import React, { useEffect, useState, useRef } from 'react';
import { Button, Space, Tree, Collapse, Divider, Message, Modal } from '@arco-design/web-react';
import { IconLeft, IconPlus, IconEdit, IconDelete, IconLink, IconSend } from '@arco-design/web-react/icon';
import styles from './style/testInstance.module.less';
import { getComponentDesign } from '@/api/componentDevelopProcess';
import {
  getComponentTestCaseList,
  submitTestCase,
  deleteTestCase,
  exportTemplate,
  exportTestCases,
  importTestCases,
  startTestCase,
  sendTestCase,
  generateTestCase
} from '@/api/componentTestCase';
import TestCaseModal from './testCaseModal';
import useWebSocket from '@/hooks/useWebSocket';
import { getToken } from '@/utils/auth';

const CollapseItem = Collapse.Item;

const TestInstance = ({ instance, parentId, onBack }: { instance: any; parentId: string; onBack: () => void }) => {
  const [activeTab, setActiveTab] = useState('link');
  const [testCaseList, setTestCaseList] = useState([]);
  const [design, setDesign] = useState(null);
  const [modalVisible, setModalVisible] = useState(false);
  const [selectedOperationIdent, setSelectedOperationIdent] = useState('');
  const [activeOperationIdent, setActiveOperationIdent] = useState('');
  const [editingTestCase, setEditingTestCase] = useState(null);
  const [logs, setLogs] = useState<string[]>([]);
  const [isSocketConnected, setIsSocketConnected] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // WebSocket hook
  const { connect, disconnect, isConnected, sendMessage } = useWebSocket({
    onOpen: () => {
      console.log('链接成功');
      setIsSocketConnected(true);
      addLog('连接信息：连接成功！');
    },
    onClose: () => {
      console.log('链接关闭');
      setIsSocketConnected(false);
      addLog('连接信息：连接已断开');
    },
    onError: () => {
      console.log('链接错误');
      addLog('连接错误：连接失败');
    },
    onMessage: (event) => {
      try {
        const data = JSON.parse(event.data);
        addLog(`收到消息: ${JSON.stringify(data)}`);
      } catch (e) {
        addLog(`收到消息: ${event.data}`);
      }
    }
  });

  // 添加日志
  const addLog = (message: string) => {
    const timestamp = new Date().toLocaleTimeString();
    setLogs(prev => [...prev, `[${timestamp}] ${message}`]);
  };

  // 清空日志
  const clearLogs = () => {
    setLogs([]);
  };

  const getDesign = async () => {
    const res: any = await getComponentDesign(parentId);
    if (res.code === 200) {
      setDesign(res.data);
      // 默认激活第一个 operation
      if (res.data?.operates?.length > 0) {
        setActiveOperationIdent(res.data.operates[0].ident);
      }
    }
  };

  const getTestCaseList = async () => {
    const res: any = await getComponentTestCaseList({ componentBaseId: parentId, identifier: instance.identifier });
    if (res.code === 200) setTestCaseList(res.data);
  };

  useEffect(() => {
    getTestCaseList();
    getDesign();
  }, [parentId, instance]);

  // 组件卸载时断开连接
  useEffect(() => {
    return () => {
      disconnect();
    };
  }, [disconnect]);


  const cryptoRandom = () => {
    return new Date().getTime().toString(16) + Math.random().toString(16).substring(2);
  };

  // 链接实例
  const handleLinkInstance = async () => {
    if (isSocketConnected) {
      disconnect();
      Message.info('已断开连接');
    }
    else {
      // WebSocket连接前置
      const res: any = await startTestCase(instance.id);
      console.log('res:', res);

      // 构建WebSocket URL，根据你的实际后端配置调整
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const host = window.location.host;
      let wsUrl = '';
      if (window.location.host.includes('localhost')) {
        wsUrl = `${process.env.NEXT_PUBLIC_DEV_SOCKET_HOST}/ws/v1/bpms-workbench/test-case/${instance.id}/${cryptoRandom()}?Authorization=Bearer ${getToken()}`;
      }
      else {
        wsUrl = `${protocol}//${host}/ws/v1/bpms-workbench/test-case/${instance.id}/${cryptoRandom()}?Authorization=Bearer ${getToken()}`;
      }

      connect(wsUrl);
      addLog('正在连接测试实例...');
    }
  };

  const handleSubmitTestCase = async (testCase: any, operationIdent: string) => {
    const res: any = await sendTestCase(testCase);
    if (res.code === 200) {
      Message.success('测试用例发送成功');
    }
    else {
      Message.error(res.msg || '测试用例发送失败');
    }
  };

  const handleAddTestCase = (operationIdent: string) => {
    setSelectedOperationIdent(operationIdent);
    setEditingTestCase(null);
    setModalVisible(true);
  };

  const handleEditTestCase = (testCase: any, operationIdent: string) => {
    setSelectedOperationIdent(operationIdent);
    setEditingTestCase(testCase);
    setModalVisible(true);
  };

  const handleDeleteTestCase = (testCase: any) => {
    Modal.confirm({
      title: '确认删除',
      content: `确定要删除测试用例"${testCase.testCaseName}"吗？`,
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        try {
          const res: any = await deleteTestCase(testCase.id);
          if (res.code === 200) {
            Message.success('删除成功');
            getTestCaseList();
          }
          else {
            Message.error(res.msg || '删除失败');
          }
        } catch (error) {
          Message.error('删除失败');
        }
      }
    });
  };

  // 导出测试用例模板
  const handleExportTemplate = async () => {
    try {
      Message.loading('正在生成模板文件...');
      const res: any = await exportTemplate(parentId);

      // 创建下载链接
      const blob = new Blob([res], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;

      // 设置文件名
      const fileName = `测试用例模板_${instance.identifier}_${new Date().getTime()}.xlsx`;
      link.setAttribute('download', fileName);

      // 触发下载
      document.body.appendChild(link);
      link.click();

      // 清理
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);

      Message.success('模板下载成功');
    } catch (error) {
      console.error('导出模板失败:', error);
      Message.error('导出模板失败');
    }
  };

  // 导出当前测试用例
  const handleExportTestCases = async () => {
    try {
      // 检查是否有测试用例
      if (!testCaseList || testCaseList.length === 0) {
        Message.warning('当前没有测试用例可导出');
        return;
      }

      Message.loading('正在生成测试用例文件...');
      const res: any = await exportTestCases(parentId);

      // 创建下载链接
      const blob = new Blob([res], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;

      // 设置文件名
      const fileName = `测试用例_${instance.identifier}_${new Date().getTime()}.xlsx`;
      link.setAttribute('download', fileName);

      // 触发下载
      document.body.appendChild(link);
      link.click();

      // 清理
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);

      Message.success('测试用例导出成功');
    } catch (error) {
      console.error('导出测试用例失败:', error);
      Message.error('导出测试用例失败');
    }
  };

  // 触发文件选择
  const handleImportClick = () => {
    fileInputRef.current?.click();
  };

  // 处理文件上传
  const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    // 验证文件类型
    const allowedTypes = [
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
      'application/vnd.ms-excel' // .xls
    ];

    if (!allowedTypes.includes(file.type) && !file.name.match(/\.(xlsx|xls)$/i)) {
      Message.error('请选择Excel文件（.xlsx 或 .xls）');
      event.target.value = ''; // 清空input
      return;
    }

    try {
      Message.loading('正在导入测试用例...');

      const res: any = await importTestCases({
        componentBaseId: parentId,
        file: file
      });

      if (res.code === 200) {
        Message.success(`导入成功！`);
        getTestCaseList(); // 刷新列表
      }
      else {
        Message.error(res.msg || '导入失败');
      }
    } catch (error) {
      console.error('导入测试用例失败:', error);
      Message.error('导入测试用例失败');
    } finally {
      // 清空input，允许重复选择同一文件
      event.target.value = '';
    }
  };

  const handleModalOk = async (values: any) => {
    const params = {
      ...values,
      componentBaseId: parentId,
      identifier: instance.identifier
    };
    const res: any = await submitTestCase(params);
    if (res.code === 200) {
      Message.success('添加测试用例成功');
      getTestCaseList();
    }
    else Message.error(res.msg);
    setModalVisible(false);
  };

  const handleModalCancel = () => {
    setModalVisible(false);
    setEditingTestCase(null);
  };

  const handleGenerateTestCases = async () => {
    const res: any = await generateTestCase({ id: design?.baseInfo.id, identifier: instance.identifier });
    if (res.code === 200) {
      Message.success('生成测试用例成功');
      getTestCaseList();
    }
    else {
      Message.error(res.msg);
    }
  };

  return (
    <div className={styles['test-instance']}>
      {/* 隐藏的文件input */}
      <input
        ref={fileInputRef}
        type="file"
        accept=".xlsx,.xls"
        style={{ display: 'none' }}
        onChange={handleFileChange}
      />

      {/* 顶部标签栏 */}
      <div className={styles['tabs']}>
        <div className={styles['tab-left']}>
          <Button
            type="primary"
            status={isSocketConnected ? 'danger' : 'default'}
            icon={<IconLink />}
            onClick={handleLinkInstance}
            style={{ minWidth: 250 }}
          >
            {isSocketConnected ? '断开实例' : '链接实例'}
          </Button>
        </div>
        <div className={styles['tab-center']}>
          <Button
            type="outline"
            status="success"
            onClick={handleGenerateTestCases}
          >
            一键生成测试用例
          </Button>
          <Button
            type="outline"
            onClick={handleExportTestCases}
          >
            下载当前测试用例模板
          </Button>
          <Button
            type="outline"
            onClick={handleImportClick}
          >
            从模板导入用例
          </Button>
          <Button
            type="outline"
            onClick={handleExportTemplate}
          >
            导出当前测试用例
          </Button>
        </div>
        <div className={styles['tab-right']}></div>
      </div>

      <div className={styles['main-content']}>
        {/* 左侧测试用例列表 */}
        <div className={styles['left-panel']}>
          <div className={styles['panel-header']}>
            <span>测试用例</span>
          </div>
          <div className={styles['tree-container']}>
            <Collapse defaultActiveKey={['1']} bordered={false} accordion>
              {testCaseList.map((item: any, index: number) => (
                <CollapseItem
                  header={
                    <div
                      style={{
                        width: '100%',
                        height: '100%',
                        display: 'flex',
                        alignItems: 'center'
                      }}
                      onClick={() => setActiveOperationIdent(item.operationIdent)}
                    >
                      {item.operationIdent}
                    </div>
                  }
                  name={index.toString()}
                  key={index}
                  extra={
                    <IconPlus
                      onClick={(e) => {
                        e.stopPropagation();
                        handleAddTestCase(item.operationIdent);
                      }}
                      style={{ cursor: 'pointer' }}
                    />
                  }
                >
                  <div className={styles['tree-list']}>
                    {item.children.map((child: any, index1: number) => (
                      <div
                        className={styles['tree-item']}
                        key={index1}
                        onClick={() => setActiveOperationIdent(item.operationIdent)}
                      >
                        <span className={styles['item-text']}>{child.testCaseName}</span>
                        <div className={styles['item-actions']}>
                          <IconSend
                            onClick={e => {
                              e.stopPropagation();
                              isSocketConnected && handleSubmitTestCase(child, item.operationIdent);
                            }}
                          />
                          <IconEdit
                            onClick={(e) => {
                              e.stopPropagation();
                              handleEditTestCase(child, item.operationIdent);
                            }}
                          />
                          <IconDelete
                            onClick={(e) => {
                              e.stopPropagation();
                              handleDeleteTestCase(child);
                            }}
                          />
                        </div>
                      </div>
                    ))}
                  </div>
                </CollapseItem>
              ))}
            </Collapse>
          </div>
        </div>

        {/* 中间流程图区域 */}
        <div className={styles['center-panel']}>
          <div className={styles['flow-wrapper']}>
            {/* 开始节点 */}
            <div className={styles['flow-node']}>
              <div className={`${styles['node-box']} ${styles['node-start']}`}>
                <div className={styles['node-header']}>
                  <span className={styles['node-title']}>开始</span>
                </div>
                <div className={styles['node-label']}>流程协作接口</div>
              </div>
              <div className={styles['node-connector']}>
                <div className={styles['connector-line']}></div>
                <div className={styles['connector-dot']}></div>
              </div>
            </div>

            {/* 组件节点 - 单个节点展示所有接口 */}
            <div className={styles['flow-node']}>
              <div className={`${styles['node-box']} ${styles['node-component']}`}>
                <div className={styles['node-header']}>
                  <span className={styles['node-title']}>{instance.identifier}</span>
                </div>
                <div className={styles['node-body']}>
                  {/* 显示所有接口函数 - 固定在上方 */}
                  {design?.operates?.map((operation: any, index: number) => (
                    <div
                      key={index}
                      className={`${styles['node-function']} ${
                        activeOperationIdent === operation.ident ? styles['active'] : ''
                      }`}
                    >
                      <span className={styles['function-dot']}></span>
                      {operation.ident}
                    </div>
                  ))}

                  {/* 分割线 */}
                  <Divider />

                  {/* 显示激活接口的参数 */}
                  {design?.operates?.map((operation: any, index: number) => (
                    activeOperationIdent === operation.ident && (
                      <div key={index}>
                        <div className={styles['node-params']}>
                          {/* Input 参数 - 显示 parameters */}
                          {operation.parameters?.map((param: any, paramIndex: number) => (
                            <div className={`${styles['param-item']} ${styles['active']}`} key={paramIndex}>
                              <span className={styles['param-dot']}></span>
                              <span className={styles['param-label']}>
                                {param.ident} {param.type}
                              </span>
                            </div>
                          ))}
                        </div>
                        {/* Output 参数 - 显示 responses */}
                        {operation.responses?.map((response: any, respIndex: number) => (
                          <div className={`${styles['param-item-right']} ${styles['active']}`} key={respIndex}>
                            <span className={styles['param-label']}>
                              {response.ident} {response.type}
                            </span>
                            <span className={styles['param-dot']}></span>
                          </div>
                        ))}
                      </div>
                    )
                  ))}
                </div>
              </div>
              <div className={styles['node-connector']}>
                <div className={styles['connector-line']}></div>
                <div className={styles['connector-dot']}></div>
              </div>
            </div>

            {/* 结束节点 */}
            <div className={styles['flow-node']}>
              <div className={`${styles['node-box']} ${styles['node-end']}`}>
                <div className={styles['node-header']}>
                  <span className={styles['node-title']}>结束</span>
                </div>
                <div className={styles['node-label']}>流程协作接口</div>
              </div>
            </div>
          </div>
        </div>

        {/* 右侧运行日志 */}
        <div className={styles['right-panel']}>
          <div className={styles['panel-header']}>
            <span>运行日志</span>
            <div className={styles['header-actions']}>
              <span className={styles['icon-btn']} onClick={clearLogs} title="清空日志">
               <IconDelete />
              </span>
            </div>
          </div>
          <div className={styles['log-content']}>
            {logs.length === 0 ? (
              <div className={styles['log-empty']}>
                <p>暂无日志信息</p>
                <p>请点击&#34;链接实例&#34;按钮连接测试实例</p>
              </div>
            ) : (
              <div className={styles['log-list']}>
                {logs.map((log, index) => (
                  <div key={index} className={styles['log-item']}>
                    {log}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>

      {modalVisible && <TestCaseModal
        design={design.operates}
        visible={modalVisible}
        operationIdent={selectedOperationIdent}
        editingData={editingTestCase}
        onCancel={handleModalCancel}
        onOk={handleModalOk}
      />}
    </div>
  );
};

export default TestInstance;