import { useState, ReactNode } from 'react';
import { Settings, SubnetInfo, AppEdge, AppNode } from '../types/graph';
import { useReactFlow} from '@xyflow/react';
import './FormEditor.css';
import Folder from './Folder';
import toast from 'react-hot-toast';
import { IPUtils } from '../utils/iputils';
import Select from 'react-select';

interface SettingEditorProps {
  settings: Settings;
  onUpdate: (data: Settings) => void;
  onClose: () => void;
}

interface SelectionOption {
  value: string;
  label: string;
}

interface SubnetProps {
  subnets: SubnetInfo[],
  setSubnets: (subnets: SubnetInfo[]) => void,
  index: number,
}

function Validate(updateData: Settings) : string[] {
  const errors: string[] = [];

  const {mtu, listenPort} = updateData;

  if(isNaN(listenPort)) {
    errors.push("监听端口不是数字");
  } else if(listenPort < 30000 || listenPort > 49151) {
    errors.push("监听端口不在范围内：[30000, 49151]");
  }

  if(isNaN(mtu)) {
    errors.push("mtu不是数字");
  } else if(mtu < 1200) {
    errors.push("mtu过小（小于1200）");
  }

  return errors;
}

function SubnetItem({index, subnets, setSubnets} : SubnetProps) : ReactNode {
  const subnetInfo = subnets[index];
  const [selectedOption, setSelectedOption] = useState<SelectionOption | null>(null);
  const [nodeSubnet, setNodeSubnet] = useState<string>("");
  const { getNodes, getNode } = useReactFlow<AppNode, AppEdge>();

  const options : SelectionOption[] = getNodes().map(node => ({
    value: node.id,
    label: node.data.label
  }));

  const handleAddNodeSubnet = () => {
    if(!selectedOption) {
      toast.error("没有选择有效的节点");
      return ;
    }
    const nodeId = selectedOption.value;
    
    const nodecidr = (() => {
      if(nodeSubnet.includes("/")) return nodeSubnet;
      return `${nodeSubnet}/${nodeSubnet.includes(".") ? "32" : "128"}`;
    })();

    const result = IPUtils.parse(nodecidr);
    const cidr = result.cidr;
    if(!cidr) {
      toast.error(`无法解析子网：${result.error}`);
      return ;
    }
    
    if(!subnetInfo.subnet.contains(cidr)) {
      toast.error("不在子网范围内");
      return ;
    }

    if(subnetInfo.nodes.some(node => node.nodeId === nodeId)) {
      toast.error(`节点已添加`);
      return;
    }

    setSubnets(subnets.map((info, idx) => {
      if(idx === index) {
        return {...info, nodes: [...info.nodes, {nodeId: nodeId, cidr: cidr}]}
      }
      return info;
    }));
  }

  const handleRemoveNodeSubnet = (nodeId: string) => {
    setSubnets(subnets.map((info, idx) => {
      if(idx === index) {
        return {...info, nodes: info.nodes.filter(node => node.nodeId != nodeId)};
      }
      return info;
    }));
  }

  const handleRemoveSubnet = () => {
    setSubnets(subnets.filter((_, idx) => idx != index));
  }

  return (<Folder title={subnetInfo.subnet.toString()}>
      <div>
        <Select
          onChange={setSelectedOption}
          options={options}
          placeholder="请选择节点..."
        />
        <input 
          type="text"
          placeholder="输入子网"
          value={nodeSubnet}
          onChange={e => {setNodeSubnet(e.target.value)}}/>
        <button onClick={_ => handleAddNodeSubnet()}>+</button>
      </div>

      {subnetInfo.nodes.map((nodeInfo, _) => {
        const node = getNode(nodeInfo.nodeId);
        if(!node) return <></>
        return (
          <div>
            <label>- {`${node.data.label}: ${nodeInfo.cidr?.toString()}`}</label>
            <button onClick={_ => handleRemoveNodeSubnet(nodeInfo.nodeId)}>删除</button>
          </div>
        )
      })}

      <div>
        <button onClick={_ => handleRemoveSubnet()}>删除子网</button>
      </div>

    </Folder>
  );
}

export default function SettingsEditor({ 
  settings,
  onUpdate, 
  onClose 
}: SettingEditorProps): ReactNode {
  const [errors, setErrors] = useState<string[]>([]);

  const [listenPort, setListenPort] = useState<number>(settings.listenPort);
  const [mtu, setmtu] = useState<number>(settings.mtu);
  const [subnets, setSubnets] = useState<SubnetInfo[]>(settings.subnets);
  const [subnetInput, setSubnetInput] = useState<string>("");

  const handleAddSubnet = (cidrStr: string) => {
    const result = IPUtils.parse(cidrStr);
    const cidr = result.cidr;
    if(!cidr) {
      toast.error(`无效的CIDR格式: ${result.error}`);
      return;
    }
    if(subnets.some(s => IPUtils.equal(s.subnet, cidr))) {
      toast.error("该CIDR已存在");
      return;
    }
    setSubnets([...subnets, {subnet: cidr, nodes: []}]);
  };

  const handleSave = (): void => {
    const updateData = {
      listenPort: listenPort,
      mtu: mtu,
      subnets: subnets
    };

    const validation = Validate(updateData);
    setErrors(validation);
    if(validation.length > 0) {
      return ;
    }

    onUpdate(updateData);
    onClose();
  };

  return (
    <div className="node-editor-overlay">
      <div className="node-editor">
        <div className="editor-header">
          <h2>全局设置</h2>
          <button className="close-btn" onClick={onClose}>×</button>
        </div>

        {errors.length > 0 && (
          <div className="error-box">
            <div 
              className="error-close-btn" 
              onClick={() => setErrors([])} // 点击清空错误数组
              title="关闭提示"
            >×</div>

            {errors.map((error, idx) => (
              <p key={idx} className="error-message">• {error}</p>
            ))}
          </div>
        )}

        <div className="form-group">
          <label>监听端口</label>
          <input
            type="number"
            min="30000"
            max="49151"
            step="1"
            value={listenPort || ""}
            onChange={e => setListenPort(e.target.valueAsNumber)}
          />
        </div>

        <div className="form-group">
          <label>mtu</label>
          <input
            type="number"
            min="1200"
            step="1"
            value={mtu || ''}
            onChange={e => setmtu(e.target.valueAsNumber)}
          />
        </div>

        <div className="form-group">
          <label>子网配置</label>
          <div className="add-subnet">
            <input 
              type="text" 
              className="subnet-input" 
              placeholder="CIDR格式的子网，例如：192.168.1.0/24"
              value={subnetInput}
              onChange={e => setSubnetInput(e.target.value)}
            />
            <button className="btn-add" onClick={e => {
              e.stopPropagation();
              handleAddSubnet(subnetInput);
            }}>+</button>
          </div>

          <div className="subnet-list">
            <label>已添加的子网：</label>
            {subnets.map((_, idx) => 
              <SubnetItem 
                key={idx} 
                index={idx}
                subnets={subnets} 
                setSubnets={setSubnets}/>)}
          </div>
          
        </div>

        <div className="editor-actions">
          <button className="btn-save" onClick={handleSave}>保存</button>
          <button className="btn-cancel" onClick={onClose}>取消</button>
        </div>
      </div>
    </div>
  );
}
