import React, { useEffect, useState } from 'react';
import {
  Box,
  Button,
  createListCollection,
  Field,
  Heading,
  HStack,
  Portal,
  Select,
  Spinner,
  Text,
  Textarea,
  VStack,
} from '@chakra-ui/react';

import DocumentTitle from '@/components/system/pages/DocumentTitle';
import PageContainer from '@/components/system/PageContainer';
import DashboardBackground from '@/components/system/pages/DashboardBackground';
import FadeInWrapper from '@/components/system/layout/FadeInWrapper';
import ConfigTool from '@/libs/config/ConfigTool';
import { api } from '@/services/api/api';
import Notification from '@/libs/system/Notification';
import Common from '@/libs/common';

const testMode = ConfigTool.load().testMode;

const ConfigPage = () => {
  const [devices, setDevices] = useState([]);
  const [selectedDevices, setSelectedDevices] = useState([]);
  const [deviceConfigs, setDeviceConfigs] = useState({});
  const [inputText, setInputText] = useState('');
  const [applying, setApplying] = useState(false);
  const [hasParsed, setHasParsed] = useState(false);

  const deviceCollection = createListCollection({
    items: devices.map((device) => ({
      label: `${device.name} (${device.ip})`,
      value: device.ip,
    })),
  });

  useEffect(() => {
    const config = ConfigTool.load();
    setDevices(config.devices || []);
  }, []);

  const handleParse = async () => {
    if (selectedDevices.length === 0 || !inputText.trim()) {
      Notification.error({
        title: '操作失败',
        description: '请选择至少一个设备并输入配置指令',
      });
      return;
    }

    const selectedConfigs = devices.filter((device) => selectedDevices.includes(device.ip));
    const deviceWithoutVendor = selectedConfigs.find((d) => !d.vendor || d.vendor.trim() === '');
    if (deviceWithoutVendor) {
      Notification.error({
        title: '操作失败',
        description: `设备 ${deviceWithoutVendor.name} 暂未配置厂商，请先配置厂商`,
      });
      return;
    }

    try {
      const performParse = async () =>
        await api.parseCommand({
          command: inputText,
          devices: selectedConfigs,
        });

      const resultWrapper = await Notification.promise({
        promise: performParse(),
        loading: {
          title: '正在解析配置',
          description: '正在分析您的指令..',
        },
        success: {
          title: '解析完成',
          description: '已生成交换机配置',
        },
        error: {
          title: '解析失败',
          description: '请检查指令格式或网络连接',
        },
      });

      let result = await resultWrapper.unwrap();
      if (result?.data?.config) {
        const configMap = {};
        result.data.config.forEach((item) => {
          if (item.device?.ip) {
            configMap[item.device.ip] = item;
          }
        });
        setDeviceConfigs(configMap);
        setHasParsed(true);
      }
    } catch (error) {
      console.error('配置解析异常:', error);
      Notification.error({
        title: '配置解析异常',
        description: error.message,
      });
    }
  };

  const handleApply = async () => {
    if (!hasParsed) {
      Notification.warn({
        title: '未解析配置',
        description: '请先解析配置再应用',
      });
      return;
    }

    setApplying(true);
    try {
      const applyOperation = async () => {
        if (testMode) {
          await Common.sleep(1000);
          Notification.success({
            title: '测试模式成功',
            description: '配置已模拟应用',
          });
          return;
        }
        const applyPromises = selectedDevices.map(async (ip) => {
          const deviceItem = deviceConfigs[ip];
          if (!deviceItem) return;

          const deviceConfig = deviceItem.config;

          if (!deviceItem.device.password) {
            Notification.warn({
              title: `交换机 ${deviceItem.device.name} 暂未配置密码`,
              description: '请前往交换机设备处配置用户名和密码',
            });
            console.log(JSON.stringify(deviceItem));
            return;
          }

          if (!deviceItem.device.username) {
            Notification.warn({
              title: `交换机 ${deviceItem.device.name} 暂未配置用户名,将使用NONE作为用户名`,
            });
            deviceItem.device.username = 'NONE';
          }

          const commands = [...deviceConfig.commands];

          try {
            const res = await api.applyConfig(
              ip,
              commands,
              deviceItem.device.username,
              deviceItem.device.password
            );
            Notification.success({
              title: `配置完毕 - ${deviceItem.device.name}`,
              description: JSON.stringify(res),
            });
          } catch (err) {
            Notification.error({
              title: `配置过程出现错误 - ${deviceItem.device.name}`,
              description: err.message || '请检查API提示',
            });
          }
        });

        await Promise.all(applyPromises);
      };

      await Notification.promise({
        promise: applyOperation(),
        loading: {
          title: '配置应用中',
          description: '正在推送配置到设备...',
        },
        success: {
          title: '应用完成',
          description: '所有设备配置已推送',
        },
        error: {
          title: '应用失败',
          description: '请检查设备连接或配置内容',
        },
      });
    } finally {
      setApplying(false);
    }
  };

  return (
    <DocumentTitle title={'交换机配置'}>
      <DashboardBackground />
      <PageContainer>
        <FadeInWrapper delay={0.3} yOffset={-5}>
          <VStack spacing={6} align={'stretch'}>
            <Heading fontSize={'xl'} color={'teal.300'}>
              交换机配置中心
            </Heading>

            <Field.Root>
              <Field.Label fontWeight={'bold'} mb={1} fontSize="sm">
                选择交换机设备
              </Field.Label>
              <Select.Root
                multiple
                collection={deviceCollection}
                value={selectedDevices}
                onValueChange={({ value }) => setSelectedDevices(value)}
                placeholder={'请选择交换机设备'}
                size={'sm'}
                colorPalette={'teal'}
              >
                <Select.HiddenSelect />
                <Select.Control>
                  <Select.Trigger>
                    <Select.ValueText />
                  </Select.Trigger>
                  <Select.IndicatorGroup>
                    <Select.Indicator />
                    <Select.ClearTrigger />
                  </Select.IndicatorGroup>
                </Select.Control>
                <Portal>
                  <Select.Positioner style={{ zIndex: 1500 }}>
                    <Select.Content>
                      {deviceCollection.items.map((item) => (
                        <Select.Item key={item.value} item={item}>
                          {item.label}
                        </Select.Item>
                      ))}
                    </Select.Content>
                  </Select.Positioner>
                </Portal>
              </Select.Root>
            </Field.Root>

            <Field.Root>
              <Field.Label fontWeight={'bold'} mb={1} fontSize="sm">
                配置指令输入
              </Field.Label>
              <Textarea
                rows={4}
                placeholder={'例：创建VLAN 10并配置IP 192.168.10.1/24并在端口1启用SSH访问'}
                value={inputText}
                colorPalette={'teal'}
                orientation={'vertical'}
                onChange={(e) => setInputText(e.target.value)}
                bg={'whiteAlpha.200'}
                size={'sm'}
              />
            </Field.Root>

            <Button
              colorScheme={'teal'}
              variant={'solid'}
              size={'sm'}
              onClick={handleParse}
              isDisabled={selectedDevices.length === 0 || !inputText.trim()}
            >
              解析配置
            </Button>

            {hasParsed && selectedDevices.length > 0 && (
              <FadeInWrapper delay={0.2}>
                <VStack spacing={4} align={'stretch'}>
                  {selectedDevices.map((ip) => {
                    const item = deviceConfigs[ip];
                    if (!item) return null;
                    const cfg = item.config;
                    return (
                      <Box
                        key={ip}
                        p={4}
                        bg={'whiteAlpha.100'}
                        borderRadius={'xl'}
                        border={'1px solid'}
                        borderColor={'whiteAlpha.300'}
                      >
                        <Text fontSize={'lg'} fontWeight={'bold'} mb={2}>
                          设备: {item.device.name} ({ip}) - 配置类型: {cfg.type}
                        </Text>

                        {Object.entries(cfg).map(([key, value]) => {
                          if (key === 'type' || key === 'commands') return null;
                          return (
                            <Field.Root
                              key={key}
                              colorPalette={'teal'}
                              orientation={'vertical'}
                              mb={3}
                            >
                              <Field.Label fontSize={'sm'}>{key}</Field.Label>
                              <Textarea
                                size={'sm'}
                                value={value}
                                onChange={(e) => {
                                  const newVal = e.target.value;
                                  setDeviceConfigs((prev) => ({
                                    ...prev,
                                    [ip]: {
                                      ...prev[ip],
                                      config: {
                                        ...prev[ip].config,
                                        [key]: newVal,
                                      },
                                    },
                                  }));
                                }}
                              />
                            </Field.Root>
                          );
                        })}

                        <Text fontWeight={'semibold'} mt={3} mb={2}>
                          配置命令:
                        </Text>
                        {cfg.commands?.map((cmd, i) => (
                          <Field.Root key={i} colorPalette={'teal'} orientation={'vertical'} mb={2}>
                            <Field.Label fontSize="sm">命令 {i + 1}</Field.Label>
                            <Textarea
                              size={'sm'}
                              fontFamily={'monospace'}
                              value={cmd}
                              onChange={(e) => {
                                const newCmd = e.target.value;
                                setDeviceConfigs((prev) => {
                                  const updated = { ...prev };
                                  updated[ip].config.commands[i] = newCmd;
                                  return updated;
                                });
                              }}
                            />
                          </Field.Root>
                        ))}

                        <HStack mt={4} spacing={3} justify={'flex-end'}>
                          <Button
                            variant={'outline'}
                            colorScheme={'gray'}
                            size={'sm'}
                            onClick={() => {
                              setDeviceConfigs((prev) => ({
                                ...prev,
                                [ip]: item,
                              }));
                              Notification.success({
                                title: '成功重置配置！',
                                description: '现在您可以重新审查生成的配置',
                              });
                            }}
                          >
                            重置为原始配置
                          </Button>

                          <Button
                            size={'sm'}
                            variant={'outline'}
                            colorScheme={'gray'}
                            onClick={() => {
                              Notification.success({
                                title: `配置 ${cfg.type} 已保存`,
                                description: '修改已同步至内存配置',
                              });
                            }}
                          >
                            保存当前配置
                          </Button>

                          <Button
                            colorScheme={'teal'}
                            size={'sm'}
                            onClick={handleApply}
                            isLoading={applying}
                            isDisabled={!cfg.commands || cfg.commands.length === 0}
                          >
                            应用到交换机
                          </Button>
                        </HStack>
                      </Box>
                    );
                  })}
                </VStack>
              </FadeInWrapper>
            )}
          </VStack>
        </FadeInWrapper>
      </PageContainer>
    </DocumentTitle>
  );
};

export default ConfigPage;
