import React, { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
import { menuApi, MenuVO, MenuType } from '../api/Menu';
import { handleTree, TreeNode } from '../utils/tree';
import { toast } from 'sonner';
import { 
  FileText, Folder, Menu, Settings, User, Users, 
  Lock, Unlock, Search, Edit, Trash2, Plus, Minus, 
  CheckCircle, X, AlertTriangle, Info, Bell, MessageSquare, 
  Phone, MapPin, Calendar, Clock, Star, Share2, 
  Download, Upload, RefreshCw, Eye, EyeOff, Home, 
  ShoppingBag, Package, Database, PieChart, BarChart3, 
  Grid3x3, List, Link2, Key, Wrench, Monitor, Server, Target
} from 'lucide-react';
import { Modal, Form, Input, Button, Radio, TreeSelect, Popover, Space, Spin } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';

interface MenuNode extends Omit<MenuVO, 'id'>, Omit<TreeNode, 'id'> {
  id: number;
  children?: MenuNode[];
}

interface MenuFormProps {
  onSuccess?: () => void;
}

export interface MenuFormRef {
  open: (type: string, id?: number, parentId?: number) => void;
}

const MenuForm = forwardRef<MenuFormRef, MenuFormProps>(({ onSuccess }, ref) => {
  const { t } = useTranslation();
  const [dialogVisible, setDialogVisible] = useState(false);
  const [dialogTitle, setDialogTitle] = useState('');
  const [formType, setFormType] = useState<'create' | 'update'>('create');
  const [formLoading, setFormLoading] = useState(false);
  const [currentId, setCurrentId] = useState<number | undefined>();
  const [menuTree, setMenuTree] = useState<MenuNode[]>([]);
  const [iconPickerOpen, setIconPickerOpen] = useState(false);
  const [form] = Form.useForm();

  const [pendingOpen, setPendingOpen] = useState<{ type: string; id?: number; parentId?: number } | null>(null);

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    open: (type: string, id?: number, parentId?: number) => {
      setDialogTitle(type === 'create' ? t('common.addNew') : t('common.edit'));
      setFormType(type as 'create' | 'update');
      setCurrentId(id);
      setPendingOpen({ type, id, parentId });
      setDialogVisible(true);
      getTree();
    },
  }));

  // 当 Modal 打开时，设置表单值
  useEffect(() => {
    if (dialogVisible && pendingOpen) {
      form.resetFields();
      
      if (pendingOpen.id) {
        loadMenuData(pendingOpen.id);
      } else {
        form.setFieldsValue({
          name: '',
          permission: '',
          type: MenuType.DIR,
          sort: 0,
          parentId: pendingOpen.parentId ?? 0,
          path: '',
          icon: '',
          component: '',
          componentName: '',
          status: 0,
          visible: true,
          keepAlive: true,
          alwaysShow: true,
        });
        setFormLoading(false);
      }
      setPendingOpen(null);
    }
  }, [dialogVisible, pendingOpen]);

  // 监听表单 icon 字段变化，确保 Input 能正确显示
  const iconValue = Form.useWatch('icon', form);

  // 组件挂载时获取菜单树
  useEffect(() => {
    getTree();
  }, []);

  // 获取菜单树
  const getTree = async () => {
    try {
      const res = await menuApi.getSimpleMenusList();
      const data = (res as any)?.data || res || [];
      const treeData = handleTree<MenuNode>(data);
      const rootMenu: MenuNode = {
        id: 0,
        name: t('form.parentMenu'),
        children: treeData,
        type: MenuType.DIR,
        sort: 0,
        parentId: 0,
        path: '',
        icon: '',
        permission: '',
        status: 0, // 0 是开启，1 是关闭
        visible: true,
        keepAlive: false,
      };
      setMenuTree([rootMenu]);
    } catch (error: any) {
      toast.error(error.message || t('common.error'));
    }
  };

  // 加载菜单数据
  const loadMenuData = async (id: number) => {
    setFormLoading(true);
    try {
      const res = await menuApi.getMenu(id);
      const data = (res as any)?.data || res;
      form.setFieldsValue({
        name: data.name,
        permission: data.permission || '',
        type: data.type,
        sort: data.sort ?? 0,
        parentId: data.parentId ?? 0,
        path: data.path || '',
        icon: data.icon || '',
        component: data.component || '',
        componentName: data.componentName || '',
        status: typeof data.status === 'string' ? Number(data.status) : (data.status ?? 0),
        visible: data.visible ?? true,
        keepAlive: data.keepAlive ?? true,
        alwaysShow: data.alwaysShow ?? true,
      });
    } catch (error: any) {
      toast.error(error.message || t('common.error'));
    } finally {
      setFormLoading(false);
    }
  };

  // 判断是否是外部链接
  const isExternal = (path: string) => {
    return /^(https?:|mailto:|tel:)/.test(path);
  };

  // 提交表单
  const submitForm = async () => {
    try {
      const values = await form.validateFields();
      setFormLoading(true);
      
      const data: MenuVO = {
        ...values,
        type: values.type,
        sort: values.sort ?? 0,
        parentId: values.parentId ?? 0,
        status: values.status ?? 0,
        visible: values.visible ?? true,
        keepAlive: values.keepAlive ?? true,
        alwaysShow: values.alwaysShow ?? true,
      };

      if (formType === 'create') {
        await menuApi.createMenu(data);
        toast.success(t('common.addSuccess'));
      } else {
        if (currentId) {
          data.id = currentId;
        }
        await menuApi.updateMenu(data);
        toast.success(t('common.updateSuccess'));
      }
      setDialogVisible(false);
      onSuccess?.();
    } catch (error: any) {
      if (error.errorFields) {
        // 表单验证错误
        return;
      }
      toast.error(error.message || t('common.saveFailed'));
    } finally {
      setFormLoading(false);
    }
  };

  // ElementPlus 图标列表（显示 React 图标，保存 ElementPlus 格式）
  const elementPlusIcons = [
    { name: 'ep:document', label: '文档', icon: FileText },
    { name: 'ep:folder', label: '文件夹', icon: Folder },
    { name: 'ep:menu', label: '菜单', icon: Menu },
    { name: 'ep:setting', label: '设置', icon: Settings },
    { name: 'ep:user', label: '用户', icon: User },
    { name: 'ep:users', label: '用户组', icon: Users },
    { name: 'ep:lock', label: '锁定', icon: Lock },
    { name: 'ep:unlock', label: '解锁', icon: Unlock },
    { name: 'ep:search', label: '搜索', icon: Search },
    { name: 'ep:edit', label: '编辑', icon: Edit },
    { name: 'ep:delete', label: '删除', icon: Trash2 },
    { name: 'ep:plus', label: '添加', icon: Plus },
    { name: 'ep:minus', label: '减少', icon: Minus },
    { name: 'ep:check', label: '确认', icon: CheckCircle },
    { name: 'ep:close', label: '关闭', icon: X },
    { name: 'ep:warning', label: '警告', icon: AlertTriangle },
    { name: 'ep:info', label: '信息', icon: Info },
    { name: 'ep:success', label: '成功', icon: CheckCircle },
    { name: 'ep:error', label: '错误', icon: X },
    { name: 'ep:bell', label: '通知', icon: Bell },
    { name: 'ep:message', label: '消息', icon: MessageSquare },
    { name: 'ep:phone', label: '电话', icon: Phone },
    { name: 'ep:location', label: '位置', icon: MapPin },
    { name: 'ep:calendar', label: '日历', icon: Calendar },
    { name: 'ep:clock', label: '时钟', icon: Clock },
    { name: 'ep:star', label: '星标', icon: Star },
    { name: 'ep:share', label: '分享', icon: Share2 },
    { name: 'ep:download', label: '下载', icon: Download },
    { name: 'ep:upload', label: '上传', icon: Upload },
    { name: 'ep:refresh', label: '刷新', icon: RefreshCw },
    { name: 'ep:view', label: '查看', icon: Eye },
    { name: 'ep:hide', label: '隐藏', icon: EyeOff },
    { name: 'ep:home', label: '首页', icon: Home },
    { name: 'ep:shop', label: '商店', icon: ShoppingBag },
    { name: 'ep:goods', label: '商品', icon: Package },
    { name: 'ep:data', label: '数据', icon: Database },
    { name: 'ep:pie-chart', label: '饼图', icon: PieChart },
    { name: 'ep:bar-chart', label: '柱状图', icon: BarChart3 },
    { name: 'ep:grid', label: '网格', icon: Grid3x3 },
    { name: 'ep:list', label: '列表', icon: List },
    { name: 'ep:connection', label: '连接', icon: Link2 },
    { name: 'ep:link', label: '链接', icon: Link2 },
    { name: 'ep:key', label: '钥匙', icon: Key },
    { name: 'ep:tools', label: '工具', icon: Wrench },
    { name: 'ep:monitor', label: '监控', icon: Monitor },
    { name: 'ep:server', label: '服务器', icon: Server },
    { name: 'ep:database', label: '数据库', icon: Database },
    { name: 'ep:aim', label: '瞄准', icon: Target },
  ];

  // 将菜单树转换为 TreeSelect 需要的格式
  const convertToTreeSelectData = (nodes: MenuNode[]): any[] => {
    return nodes.map(node => ({
      title: node.name,
      value: node.id,
      key: node.id,
      disabled: node.id === currentId,
      children: node.children ? convertToTreeSelectData(node.children) : undefined,
    }));
  };

  return (
    <Modal
      title={dialogTitle}
      open={dialogVisible}
      onCancel={() => {
        setDialogVisible(false);
        setPendingOpen(null);
      }}
      onOk={submitForm}
      confirmLoading={formLoading}
      okText={t('common.confirm')}
      cancelText={t('common.cancel')}
      width={720}
      destroyOnClose
    >
      <Spin spinning={formLoading && formType === 'update'}>
        <Form
          form={form}
          layout="horizontal"
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          initialValues={{
            type: MenuType.DIR,
            sort: 0,
            parentId: 0,
            status: 0,
            visible: true,
            keepAlive: true,
            alwaysShow: true,
          }}
        >
          <Form.Item
            label={t('form.parentMenu')}
            name="parentId"
          >
            <TreeSelect
              treeData={convertToTreeSelectData(menuTree)}
              placeholder={t('form.parentMenuPlaceholder')}
              disabled={!menuTree || menuTree.length === 0}
              treeDefaultExpandAll
            />
          </Form.Item>

          <Form.Item
            label={t('form.menuName')}
            name="name"
            rules={[
              { required: true, message: t('form.menuNamePlaceholder') },
              { max: 50, message: t('common.error') },
            ]}
          >
            <Input placeholder={t('form.menuNamePlaceholder')} />
          </Form.Item>

          <Form.Item
            label={t('form.menuType')}
            name="type"
            rules={[{ required: true, message: t('common.pleaseSelect') }]}
          >
            <Radio.Group buttonStyle="solid" optionType="button">
              <Radio.Button value={MenuType.DIR}>{t('form.menuDir')}</Radio.Button>
              <Radio.Button value={MenuType.MENU}>{t('form.menuMenu')}</Radio.Button>
              <Radio.Button value={MenuType.BUTTON}>{t('form.menuButton')}</Radio.Button>
            </Radio.Group>
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') !== MenuType.BUTTON ? (
                <Form.Item label={t('form.menuIcon')} name="icon">
                  <Space.Compact style={{ width: '100%' }}>
                    <Input
                      placeholder={t('form.menuIconPlaceholder')}
                      value={iconValue || ''}
                      onChange={(e) => {
                        form.setFieldsValue({ icon: e.target.value });
                      }}
                    />
                    <Popover
                      content={
                        <div style={{ width: 400 }}>
                          <h4 style={{ marginBottom: 8, fontSize: 14, fontWeight: 600 }}>{t('form.menuIcon')}</h4>
                          <div 
                            style={{ 
                              display: 'grid',
                              gridTemplateColumns: 'repeat(8, 1fr)',
                              gap: 6,
                              maxHeight: 300,
                              overflowY: 'auto'
                            }}
                          >
                            {elementPlusIcons.map((iconItem) => {
                              const IconComponent = iconItem.icon;
                              const currentIcon = form.getFieldValue('icon');
                              const isSelected = currentIcon === iconItem.name;
                              return (
                                <div
                                  key={iconItem.name}
                                  onClick={() => {
                                    // 设置表单字段值，会自动更新 Input 框
                                    form.setFieldsValue({ icon: iconItem.name });
                                    // 关闭 Popover
                                    setIconPickerOpen(false);
                                    // 强制触发表单更新，确保 Input 框显示最新值
                                    form.validateFields(['icon']).catch(() => {});
                                  }}
                                  style={{
                                    display: 'flex',
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    padding: 6,
                                    borderRadius: 4,
                                    cursor: 'pointer',
                                    border: `1px solid ${isSelected ? '#1890ff' : '#d9d9d9'}`,
                                    backgroundColor: isSelected ? '#e6f7ff' : '#fff',
                                    aspectRatio: '1'
                                  }}
                                  title={`${iconItem.name} - ${iconItem.label}`}
                                >
                                  <IconComponent 
                                    style={{ 
                                      width: 14,
                                      height: 14,
                                      color: isSelected ? '#1890ff' : '#666'
                                    }}
                                  />
                                </div>
                              );
                            })}
                          </div>
                        </div>
                      }
                      title={t('form.menuIcon')}
                      trigger="click"
                      open={iconPickerOpen}
                      onOpenChange={setIconPickerOpen}
                    >
                      <Button type="primary">{t('form.menuIcon')}</Button>
                    </Popover>
                  </Space.Compact>
                </Form.Item>
              ) : null
            }
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') !== MenuType.BUTTON ? (
                <Form.Item
                  label={
                    <span>
                      {t('form.routePath')}
                      <QuestionCircleOutlined style={{ fontSize: 14, color: '#999', marginLeft: 4 }} />
                    </span>
                  }
                  name="path"
                  rules={[
                    { required: true, message: t('form.routePathPlaceholder') },
                    ({ getFieldValue }) => ({
                      validator(_, value) {
                        if (!value) {
                          return Promise.resolve();
                        }
                        const parentId = getFieldValue('parentId');
                        const isExternal = /^(https?:|mailto:|tel:)/.test(value);
                        if (!isExternal) {
                          if (parentId === 0 && value.charAt(0) !== '/') {
                            return Promise.reject(new Error(t('form.routePathRuleRoot')));
                          } else if (parentId !== 0 && value.charAt(0) === '/') {
                            return Promise.reject(new Error(t('form.routePathRuleChild')));
                          }
                        }
                        return Promise.resolve();
                      },
                    }),
                  ]}
                >
                  <Input placeholder={t('form.routePathPlaceholder')} />
                </Form.Item>
              ) : null
            }
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') === MenuType.MENU ? (
                <>
                  <Form.Item label={t('form.componentPathLabel')} name="component">
                    <Input placeholder={t('form.componentPathExample')} />
                  </Form.Item>
                  <Form.Item label={t('form.componentNameLabel')} name="componentName">
                    <Input placeholder={t('form.componentNameExample')} />
                  </Form.Item>
                </>
              ) : null
            }
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') !== MenuType.DIR ? (
                <Form.Item
                  label={
                    <span>
                      {t('form.permission')}
                      <QuestionCircleOutlined style={{ fontSize: 14, color: '#999', marginLeft: 4 }} />
                    </span>
                  }
                  name="permission"
                >
                  <Input placeholder={t('form.permissionPlaceholder')} />
                </Form.Item>
              ) : null
            }
          </Form.Item>

          <Form.Item
            label={t('form.displayOrder')}
            name="sort"
            rules={[{ required: true, message: t('form.displayOrderPlaceholder') }]}
          >
            <Input type="number" placeholder={t('form.displayOrderPlaceholder')} min={0} />
          </Form.Item>

          <Form.Item
            label={t('form.menuStatus')}
            name="status"
            rules={[{ required: true, message: t('common.pleaseSelect') }]}
          >
            <Radio.Group buttonStyle="solid" optionType="button">
              <Radio.Button value={0}>{t('form.statusOpen')}</Radio.Button>
              <Radio.Button value={1}>{t('form.statusClose')}</Radio.Button>
            </Radio.Group>
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') !== MenuType.BUTTON ? (
                <>
                  <Form.Item
                    label={
                      <span>
                        {t('form.visibleStatus')}
                        <QuestionCircleOutlined style={{ fontSize: 14, color: '#999', marginLeft: 4 }} />
                      </span>
                    }
                    name="visible"
                  >
                    <Radio.Group buttonStyle="solid" optionType="button">
                      <Radio.Button value={true}>{t('form.visibleShow')}</Radio.Button>
                      <Radio.Button value={false}>{t('form.visibleHide')}</Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                  <Form.Item
                    label={
                      <span>
                        {t('form.alwaysShow')}
                        <QuestionCircleOutlined style={{ fontSize: 14, color: '#999', marginLeft: 4 }} />
                      </span>
                    }
                    name="alwaysShow"
                  >
                    <Radio.Group buttonStyle="solid" optionType="button">
                      <Radio.Button value={true}>{t('form.always')}</Radio.Button>
                      <Radio.Button value={false}>{t('form.notAlways')}</Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </>
              ) : null
            }
          </Form.Item>

          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
          >
            {({ getFieldValue }) =>
              getFieldValue('type') === MenuType.MENU ? (
                <Form.Item
                  label={
                    <span>
                      {t('form.cacheStatus')}
                      <QuestionCircleOutlined style={{ fontSize: 14, color: '#999', marginLeft: 4 }} />
                    </span>
                  }
                  name="keepAlive"
                >
                  <Radio.Group buttonStyle="solid" optionType="button">
                    <Radio.Button value={true}>{t('form.cache')}</Radio.Button>
                    <Radio.Button value={false}>{t('form.notCache')}</Radio.Button>
                  </Radio.Group>
                </Form.Item>
              ) : null
            }
          </Form.Item>
        </Form>
      </Spin>
    </Modal>
  );
});

MenuForm.displayName = 'MenuForm';

export default MenuForm;


