import { 
  Modal, 
  ModalContent, 
  ModalHeader, 
  ModalBody, 
  ModalFooter, 
  Button,
  Chip,
  Input,
  Select,
  SelectItem,
  Autocomplete,
  AutocompleteItem,
  Checkbox,
  Divider
} from '@heroui/react'
import React, { useEffect, useState } from 'react'
import { getProfileStr, setProfileStr } from '@renderer/utils/ipc'
import { useTranslation } from 'react-i18next'
import yaml from 'js-yaml'
import { IoMdTrash, IoMdArrowUp, IoMdArrowDown, IoMdUndo } from 'react-icons/io'
import { MdVerticalAlignTop, MdVerticalAlignBottom } from 'react-icons/md'

interface Props {
  id: string
  onClose: () => void
}

interface RuleItem {
  type: string
  payload: string
  proxy: string
  additionalParams?: string[]
}

// 内置路由规则 https://wiki.metacubex.one/config/rules/
const ruleTypes = [
  'DOMAIN',
  'DOMAIN-SUFFIX',
  'DOMAIN-KEYWORD',
  'DOMAIN-WILDCARD',
  'DOMAIN-REGEX',
  'GEOSITE',
  'IP-CIDR',
  'IP-CIDR6',
  'IP-SUFFIX',
  'IP-ASN',
  'GEOIP',
  'SRC-GEOIP',
  'SRC-IP-ASN',
  'SRC-IP-CIDR',
  'SRC-IP-SUFFIX',
  'DST-PORT',
  'SRC-PORT',
  'IN-PORT',
  'IN-TYPE',
  'IN-USER',
  'IN-NAME',
  'PROCESS-PATH',
  'PROCESS-PATH-REGEX',
  'PROCESS-NAME',
  'PROCESS-NAME-REGEX',
  'UID',
  'NETWORK',
  'DSCP',
  'RULE-SET',
  'AND',
  'OR',
  'NOT',
  'SUB-RULE',
  'MATCH'
]

// 支持 no-resolve 参数的规则类型
const noResolveSupportTypes = [
  'IP-CIDR',
  'IP-CIDR6',
  'IP-SUFFIX',
  'IP-ASN',
  'GEOIP'
]

// 支持 src 参数的规则类型
const srcSupportTypes = [
  'IP-CIDR',
  'IP-CIDR6',
  'IP-SUFFIX',
  'IP-ASN',
  'GEOIP'
]

const EditRulesModal: React.FC<Props> = (props) => {
  const { id, onClose } = props
  const [rules, setRules] = useState<RuleItem[]>([])
  const [filteredRules, setFilteredRules] = useState<RuleItem[]>([])
  const [profileContent, setProfileContent] = useState('')
  const [newRule, setNewRule] = useState<RuleItem>({ type: 'DOMAIN', payload: '', proxy: 'DIRECT', additionalParams: [] })
  const [searchTerm, setSearchTerm] = useState('')
  const [proxyGroups, setProxyGroups] = useState<string[]>([])
  const [deletedRules, setDeletedRules] = useState<Set<number>>(new Set()) // Store indices of deleted rules
  const { t } = useTranslation()

  const getContent = async (): Promise<void> => {
    const content = await getProfileStr(id)
    setProfileContent(content)
    
    try {
      const parsed = yaml.load(content) as any
      if (parsed && parsed.rules && Array.isArray(parsed.rules)) {
        const parsedRules = parsed.rules.map((rule: string) => {
          const parts = rule.split(',')
          if (parts[0] === 'MATCH') {
            return {
              type: 'MATCH',
              proxy: parts[1]
            }
          } else {
            const additionalParams = parts.slice(3).filter(param => param.trim() !== '') || []
            return {
              type: parts[0],
              payload: parts[1],
              proxy: parts[2],
              additionalParams
            }
          }
        })
        setRules(parsedRules)
        setFilteredRules(parsedRules)
      }
      
      // 从配置文件中提取代理组
      if (parsed) {
        const groups: string[] = []
        
        // 添加代理组名称
        if (Array.isArray(parsed['proxy-groups'])) {
          groups.push(...parsed['proxy-groups'].map((group: any) => group?.name).filter(Boolean))
        }
        
        // 添加代理名称
        if (Array.isArray(parsed['proxies'])) {
          groups.push(...parsed['proxies'].map((proxy: any) => proxy?.name).filter(Boolean))
        }
        
        // 预置出站 https://wiki.metacubex.one/config/proxies/built-in/
        groups.push('DIRECT', 'REJECT', 'REJECT-DROP', 'PASS', 'COMPATIBLE')
        
        // 去重
        setProxyGroups([...new Set(groups)])
      }
    } catch (e) {
      console.error('解析配置文件内容失败', e)
    }
  }

  useEffect(() => {
    getContent()
  }, [])

  useEffect(() => {
    if (searchTerm === '') {
      setFilteredRules(rules)
    } else {
      const filtered = rules.filter(rule => 
        rule.type.toLowerCase().includes(searchTerm.toLowerCase()) ||
        rule.payload.toLowerCase().includes(searchTerm.toLowerCase()) ||
        (rule.proxy && rule.proxy.toLowerCase().includes(searchTerm.toLowerCase())) ||
        (rule.additionalParams && rule.additionalParams.some(param => param.toLowerCase().includes(searchTerm.toLowerCase())))
      )
      setFilteredRules(filtered)
    }
  }, [searchTerm, rules])

  const handleSave = async (): Promise<void> => {
    try {
      // 过滤掉已标记为删除的规则
      const rulesToSave = rules.filter((_, index) => !deletedRules.has(index));
      
      // 将规则转换回字符串格式
      const ruleStrings = rulesToSave.map(rule => {
        const parts = [rule.type]
        if (rule.payload) parts.push(rule.payload)
        if (rule.proxy) parts.push(rule.proxy)
        if (rule.additionalParams && rule.additionalParams.length > 0) {
          parts.push(...rule.additionalParams)
        }
        return parts.join(',')
      })
      
      // 直接在原始内容中替换规则部分，保持原有格式
      let updatedContent = profileContent
      
      // 将内容按行分割，便于处理
      const lines = profileContent.split('\n')
      const newLines: string[] = []
      let inRulesSection = false
      let rulesSectionFound = false
      let rulesIndent = ''
      
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i]
        const trimmedLine = line.trim()
        
        // 检查是否是 rules: 开始行
        if (trimmedLine === 'rules:') {
          rulesSectionFound = true
          inRulesSection = true
          rulesIndent = line.match(/^\s*/)?.[0] || ''
          newLines.push(line) // 保留 rules: 行
          
          // 添加新的规则行
          for (const rule of ruleStrings) {
            newLines.push(`${rulesIndent}  - ${rule}`)
          }
          
          // 跳过原有的 rules 内容
          while (i + 1 < lines.length) {
            const nextLine = lines[i + 1]
            const nextTrimmed = nextLine.trim()
            const nextIndent = nextLine.match(/^\s*/)?.[0] || ''
            
            // 如果下一行不是空行且缩进大于 rules 缩进，说明还是 rules 的内容
            if (nextTrimmed !== '' && nextIndent.length > rulesIndent.length) {
              i++ // 跳过这一行
            } else {
              break
            }
          }
          continue
        }
        
        // 如果在 rules 部分中，跳过处理
        if (inRulesSection && trimmedLine.startsWith('-')) {
          // 检查是否还有 rules 行
          const currentIndent = line.match(/^\s*/)?.[0] || ''
          if (currentIndent.length > rulesIndent.length) {
            continue // 跳过原有规则行
          } else {
            inRulesSection = false // rules 部分结束
          }
        }
        
        newLines.push(line)
      }
      
      // 如果没有找到 rules 部分，添加到文件末尾
      if (!rulesSectionFound) {
        newLines.push('') // 空行
        newLines.push('rules:')
        for (const rule of ruleStrings) {
          newLines.push(`  - ${rule}`)
        }
      }
      
      updatedContent = newLines.join('\n')
      
      await setProfileStr(id, updatedContent)
      onClose()
    } catch (e) {
      alert(t('profiles.editRules.saveError') + ': ' + (e instanceof Error ? e.message : String(e)))
    }
  }

  const handleRuleTypeChange = (selected: string): void => {
    const noResolveSupported = noResolveSupportTypes.includes(selected);
    const srcSupported = srcSupportTypes.includes(selected);

    let additionalParams = [...(newRule.additionalParams || [])];
    if (!noResolveSupported) {
      additionalParams = additionalParams.filter(param => param !== 'no-resolve');
    }
    if (!srcSupported) {
      additionalParams = additionalParams.filter(param => param !== 'src');
    }
    
    setNewRule({
      ...newRule,
      type: selected,
      additionalParams: additionalParams.length > 0 ? additionalParams : []
    });
  };

  const handleAdditionalParamChange = (param: string, checked: boolean): void => {
    let newAdditionalParams = [...(newRule.additionalParams || [])];
    
    if (checked) {
      if (!newAdditionalParams.includes(param)) {
        newAdditionalParams.push(param);
      }
    } else {
      newAdditionalParams = newAdditionalParams.filter(p => p !== param);
    }
    
    setNewRule({ 
      ...newRule, 
      additionalParams: newAdditionalParams
    });
  };

  const handleAddRule = (position: 'prepend' | 'append' = 'append'): void => {
    if (newRule.payload.trim() !== '' || newRule.type === 'MATCH') {
      const newRuleItem = { ...newRule };
      let updatedRules: RuleItem[];
      
      if (position === 'prepend') {
        updatedRules = [newRuleItem, ...rules];
      } else {
        updatedRules = [...rules, newRuleItem];
      }
      
      setRules(updatedRules)
      setFilteredRules(updatedRules)
      setNewRule({ type: 'DOMAIN', payload: '', proxy: 'DIRECT', additionalParams: [] })
    }
  }

  const handleRemoveRule = (index: number): void => {
    setDeletedRules(prev => {
      const newSet = new Set(prev)
      if (newSet.has(index)) {
        newSet.delete(index) // 如果已经标记为删除，则取消标记
      } else {
        newSet.add(index) // 标记为删除
      }
      return newSet
    })
  }

  const handleMoveRuleUp = (index: number): void => {
    if (index <= 0) return
    const updatedRules = [...rules]
    const temp = updatedRules[index]
    updatedRules[index] = updatedRules[index - 1]
    updatedRules[index - 1] = temp
    setRules(updatedRules)
    setFilteredRules(updatedRules)
    setDeletedRules(prev => {
      const newSet = new Set<number>()
      prev.forEach(idx => {
        if (idx === index) {
          newSet.add(index - 1)
        } else if (idx === index - 1) {
          newSet.add(index)
        } else {
          newSet.add(idx)
        }
      })
      return newSet
    })
  }

  const handleMoveRuleDown = (index: number): void => {
    if (index >= rules.length - 1) return
    const updatedRules = [...rules]
    const temp = updatedRules[index]
    updatedRules[index] = updatedRules[index + 1]
    updatedRules[index + 1] = temp
    setRules(updatedRules)
    setFilteredRules(updatedRules)
    setDeletedRules(prev => {
      const newSet = new Set<number>()
      prev.forEach(idx => {
        if (idx === index) {
          newSet.add(index + 1)
        } else if (idx === index + 1) {
          newSet.add(index)
        } else {
          newSet.add(idx)
        }
      })
      return newSet
    })
  }

  return (
    <Modal
      backdrop="blur"
      classNames={{ backdrop: 'top-[48px]' }}
      size="5xl"
      hideCloseButton
      isOpen={true}
      onOpenChange={onClose}
      scrollBehavior="inside"
    >
      <ModalContent className="h-full w-[calc(100%-100px)]">
        <ModalHeader className="flex pb-0 app-drag">
          <div className="flex justify-start">
            <div className="flex items-center">{t('profiles.editRules.title')}</div>
          </div>
        </ModalHeader>
        <ModalBody className="h-full">
          <div className="flex gap-4 h-full">
            {/* 左侧面板 - 规则表单 */}
            <div className="w-1/3 flex flex-col gap-4">
              <div className="flex flex-col gap-2">
                <Select
                  label={t('profiles.editRules.ruleType')}
                  selectedKeys={[newRule.type]}
                  onSelectionChange={(keys) => {
                    const selected = Array.from(keys)[0] as string
                    handleRuleTypeChange(selected)
                  }}
                >
                  {ruleTypes.map((type) => (
                    <SelectItem key={type}>
                      {type}
                    </SelectItem>
                  ))}
                </Select>
                
                <Input
                  label={t('profiles.editRules.payload')}
                  placeholder={t('profiles.editRules.payloadPlaceholder')}
                  value={newRule.payload}
                  onValueChange={(value) => setNewRule({ ...newRule, payload: value })}
                  isDisabled={newRule.type === 'MATCH'}
                />
                
                <Autocomplete
                  label={t('profiles.editRules.proxy')}
                  placeholder={t('profiles.editRules.proxyPlaceholder')}
                  selectedKey={newRule.proxy}
                  onSelectionChange={(key) => setNewRule({ ...newRule, proxy: key as string })}
                  inputValue={newRule.proxy}
                  onInputChange={(value) => setNewRule({ ...newRule, proxy: value })}
                >
                  {proxyGroups.map((group) => (
                    <AutocompleteItem key={group} textValue={group}>
                      {group}
                    </AutocompleteItem>
                  ))}
                </Autocomplete>
                
                {/* 附加参数 */}
                {(noResolveSupportTypes.includes(newRule.type) || srcSupportTypes.includes(newRule.type)) && (
                  <>
                    <Divider className="my-2" />
                    <div className="flex flex-col gap-2">
                      {noResolveSupportTypes.includes(newRule.type) && (
                        <Checkbox
                          isSelected={newRule.additionalParams?.includes('no-resolve') || false}
                          onValueChange={(checked) => handleAdditionalParamChange('no-resolve', checked)}
                        >
                          {t('profiles.editRules.noResolve')}
                        </Checkbox>
                      )}
                      {srcSupportTypes.includes(newRule.type) && (
                        <Checkbox
                          isSelected={newRule.additionalParams?.includes('src') || false}
                          onValueChange={(checked) => handleAdditionalParamChange('src', checked)}
                        >
                          {t('profiles.editRules.src')}
                        </Checkbox>
                      )}
                    </div>
                  </>
                )}
                
                <div className="flex flex-col gap-2">
                  <Button 
                    color="primary" 
                    onPress={() => handleAddRule('prepend')}
                    isDisabled={!(newRule.payload.trim() || newRule.type === 'MATCH') || !newRule.type}
                    startContent={<MdVerticalAlignTop className="text-lg" />}
                  >
                    {t('profiles.editRules.addRulePrepend')}
                  </Button>
                  <Button 
                    color="primary" 
                    variant="bordered"
                    onPress={() => handleAddRule('append')}
                    isDisabled={!(newRule.payload.trim() || newRule.type === 'MATCH') || !newRule.type}
                    startContent={<MdVerticalAlignBottom className="text-lg" />}
                  >
                    {t('profiles.editRules.addRuleAppend')}
                  </Button>
                </div>
              </div>
              
              <div className="flex-1 border-t border-divider pt-4">
                <h3 className="text-lg font-semibold mb-2">{t('profiles.editRules.instructions')}</h3>
                <div className="text-sm text-foreground-500">
                  <p className="mb-2">{t('profiles.editRules.instructions1')}</p>
                  <p className="mb-2">{t('profiles.editRules.instructions2')}</p>
                  <p>{t('profiles.editRules.instructions3')}</p>
                </div>
              </div>
            </div>
            
            {/* 右侧面板 - 规则列表 */}
            <div className="w-2/3 border-l border-divider pl-4 flex flex-col">
              <div className="flex justify-between items-center mb-2">
                <h3 className="text-lg font-semibold">{t('profiles.editRules.currentRules')}</h3>
                <Input
                  size="sm"
                  placeholder={t('profiles.editRules.searchPlaceholder')}
                  className="w-1/3"
                  value={searchTerm}
                  onValueChange={setSearchTerm}
                />
              </div>
              <div className="flex flex-col gap-2 max-h-[calc(100vh-200px)] overflow-y-auto flex-1">
                {filteredRules.length === 0 ? (
                  <div className="text-center text-foreground-500 py-4">
                    {rules.length === 0 
                      ? t('profiles.editRules.noRules') 
                      : searchTerm 
                        ? t('profiles.editRules.noMatchingRules') 
                        : t('profiles.editRules.noRules')}
                  </div>
                ) : (
                  filteredRules.map((rule) => {
                    const originalIndex = rules.indexOf(rule);
                    return (
                      <div key={originalIndex} className={`flex items-center gap-2 p-2 rounded-lg ${deletedRules.has(originalIndex) ? 'bg-danger-50 opacity-70' : 'bg-content2'}`}>
                        <div className="flex flex-col">
                          <div className="flex items-center gap-1">
                            <Chip size="sm" variant="flat">
                              {rule.type}
                            </Chip>
                            {/* 显示附加参数 */}
                            <div className="flex gap-1">
                              {rule.additionalParams && rule.additionalParams.length > 0 && (
                                rule.additionalParams.map((param, idx) => (
                                  <Chip key={idx} size="sm" variant="flat" color="secondary">{param}</Chip>
                                ))
                              )}  
                            </div>
                          </div>
                        </div>
                        <div className="flex-1 min-w-0">
                          <div className="font-medium truncate">
                            {rule.type === 'MATCH' ? rule.proxy : rule.payload}
                          </div>
                          {rule.proxy && rule.type !== 'MATCH' && (
                            <div className="text-sm text-foreground-500 truncate">{rule.proxy}</div>
                          )}
                        </div>
                        <div className="flex gap-1">
                          <Button 
                            size="sm" 
                            variant="light"
                            onPress={() => handleMoveRuleUp(originalIndex)}
                            isIconOnly
                            isDisabled={originalIndex === 0 || deletedRules.has(originalIndex)}
                          >
                            <IoMdArrowUp className="text-lg" />
                          </Button>
                          <Button 
                            size="sm" 
                            variant="light"
                            onPress={() => handleMoveRuleDown(originalIndex)}
                            isIconOnly
                            isDisabled={originalIndex === rules.length - 1 || deletedRules.has(originalIndex)}
                          >
                            <IoMdArrowDown className="text-lg" />
                          </Button>
                          <Button 
                            size="sm" 
                            color={deletedRules.has(originalIndex) ? "success" : "danger"}
                            variant="light"
                            onPress={() => handleRemoveRule(originalIndex)}
                            isIconOnly
                          >
                            {deletedRules.has(originalIndex) ? <IoMdUndo className="text-lg" /> : <IoMdTrash className="text-lg" />}
                          </Button>
                        </div>
                      </div>
                    )
                  })
                )}
              </div>
            </div>
          </div>
        </ModalBody>
        <ModalFooter className="pt-0">
          <Button size="sm" variant="light" onPress={() => {
            setDeletedRules(new Set()) // 清除删除状态
            onClose()
          }}>
            {t('common.cancel')}
          </Button>
          <Button
            size="sm"
            color="primary"
            onPress={handleSave}
          >
            {t('common.save')}
          </Button>
        </ModalFooter>
      </ModalContent>
    </Modal>
  )
}

export default EditRulesModal