import { useState, useEffect, useCallback } from 'react';
import {
  Table,
  Button,
  Space,
  Modal,
  Form,
  Input,
  InputNumber,
  Select,
  Switch,
  TreeSelect,
  Popconfirm,
  message,
  Typography,
  Tag,
} from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import client from '../../api/client';

// --- Types ---

interface MenuItem {
  id: string;
  parent_id?: string | null;
  title: string;
  path?: string;
  icon?: string;
  menu_type: 'directory' | 'menu' | 'button';
  sort_order: number;
  visible: boolean;
  permission?: string;
  children?: MenuItem[];
}

// --- Helpers ---

/** Convert flat menu list to tree structure for Table children prop */
function buildMenuTree(items: MenuItem[]): MenuItem[] {
  const map = new Map<string, MenuItem>();
  const roots: MenuItem[] = [];

  const withChildren = items.map((item) => ({
    ...item,
    children: [] as MenuItem[],
  }));

  withChildren.forEach((item) => map.set(item.id, item));

  withChildren.forEach((item) => {
    if (item.parent_id && map.has(item.parent_id)) {
      map.get(item.parent_id)!.children!.push(item);
    } else {
      roots.push(item);
    }
  });

  return roots;
}

/** Convert menu tree to TreeSelect data nodes */
function toTreeSelectData(
  items: MenuItem[],
): Array<{ title: string; value: string; children?: Array<{ title: string; value: string }> }> {
  return items.map((item) => ({
    title: item.title,
    value: item.id,
    children:
      item.children && item.children.length > 0
        ? toTreeSelectData(item.children)
        : undefined,
  }));
}

const menuTypeLabels: Record<string, { text: string; color: string }> = {
  directory: { text: '目录', color: 'blue' },
  menu: { text: '菜单', color: 'green' },
  button: { text: '按钮', color: 'orange' },
};

// --- Component ---

export default function MenuConfig() {
  const [menus, setMenus] = useState<MenuItem[]>([]);
  const [menuTree, setMenuTree] = useState<MenuItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [editMenu, setEditMenu] = useState<MenuItem | null>(null);
  const [form] = Form.useForm();

  const fetchMenus = useCallback(async () => {
    setLoading(true);
    try {
      const { data: resp } = await client.get('/config/menus');
      const list: MenuItem[] = resp.data ?? resp;
      setMenus(list);
      setMenuTree(buildMenuTree(list));
    } catch {
      message.error('加载菜单失败');
    }
    setLoading(false);
  }, []);

  useEffect(() => {
    fetchMenus();
  }, [fetchMenus]);

  const handleSubmit = async (values: {
    parent_id?: string;
    title: string;
    path?: string;
    icon?: string;
    menu_type: 'directory' | 'menu' | 'button';
    sort_order: number;
    visible: boolean;
    permission?: string;
  }) => {
    try {
      if (editMenu) {
        await client.put(`/config/menus/${editMenu.id}`, values);
        message.success('菜单更新成功');
      } else {
        await client.post('/config/menus', values);
        message.success('菜单创建成功');
      }
      closeModal();
      fetchMenus();
    } catch (err: unknown) {
      const errorMsg =
        (err as { response?: { data?: { message?: string } } })?.response?.data
          ?.message || '操作失败';
      message.error(errorMsg);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await client.delete(`/config/menus/${id}`);
      message.success('菜单已删除');
      fetchMenus();
    } catch {
      message.error('删除失败');
    }
  };

  const openCreate = () => {
    setEditMenu(null);
    form.resetFields();
    form.setFieldsValue({
      menu_type: 'menu',
      sort_order: 0,
      visible: true,
    });
    setModalOpen(true);
  };

  const openEdit = (menu: MenuItem) => {
    setEditMenu(menu);
    form.setFieldsValue({
      parent_id: menu.parent_id || undefined,
      title: menu.title,
      path: menu.path,
      icon: menu.icon,
      menu_type: menu.menu_type,
      sort_order: menu.sort_order,
      visible: menu.visible,
      permission: menu.permission,
    });
    setModalOpen(true);
  };

  const closeModal = () => {
    setModalOpen(false);
    setEditMenu(null);
    form.resetFields();
  };

  const columns = [
    { title: '标题', dataIndex: 'title', key: 'title', width: 200 },
    {
      title: '路径',
      dataIndex: 'path',
      key: 'path',
      ellipsis: true,
      render: (v?: string) => v || '-',
    },
    {
      title: '图标',
      dataIndex: 'icon',
      key: 'icon',
      width: 100,
      render: (v?: string) => v || '-',
    },
    {
      title: '类型',
      dataIndex: 'menu_type',
      key: 'menu_type',
      width: 90,
      render: (v: string) => {
        const info = menuTypeLabels[v] ?? { text: v, color: 'default' };
        return <Tag color={info.color}>{info.text}</Tag>;
      },
    },
    {
      title: '排序',
      dataIndex: 'sort_order',
      key: 'sort_order',
      width: 80,
    },
    {
      title: '可见',
      dataIndex: 'visible',
      key: 'visible',
      width: 80,
      render: (v: boolean) =>
        v ? <Tag color="green">是</Tag> : <Tag color="default">否</Tag>,
    },
    {
      title: '操作',
      key: 'actions',
      width: 150,
      render: (_: unknown, record: MenuItem) => (
        <Space>
          <Button size="small" onClick={() => openEdit(record)}>
            编辑
          </Button>
          <Popconfirm
            title="确定删除此菜单？"
            onConfirm={() => handleDelete(record.id)}
          >
            <Button size="small" danger>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          marginBottom: 16,
        }}
      >
        <Typography.Title level={5} style={{ margin: 0 }}>
          菜单配置
        </Typography.Title>
        <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
          添加菜单
        </Button>
      </div>

      <Table
        columns={columns}
        dataSource={menuTree}
        rowKey="id"
        loading={loading}
        pagination={false}
        indentSize={20}
      />

      <Modal
        title={editMenu ? '编辑菜单' : '添加菜单'}
        open={modalOpen}
        onCancel={closeModal}
        onOk={() => form.submit()}
        width={560}
      >
        <Form form={form} onFinish={handleSubmit} layout="vertical">
          <Form.Item name="parent_id" label="上级菜单">
            <TreeSelect
              treeData={toTreeSelectData(menuTree)}
              placeholder="无（顶级菜单）"
              allowClear
              treeDefaultExpandAll
            />
          </Form.Item>
          <Form.Item
            name="title"
            label="标题"
            rules={[{ required: true, message: '请输入菜单标题' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item name="path" label="路径">
            <Input placeholder="/example/path" />
          </Form.Item>
          <Form.Item name="icon" label="图标">
            <Input placeholder="图标名称，如 HomeOutlined" />
          </Form.Item>
          <Form.Item
            name="menu_type"
            label="类型"
            rules={[{ required: true, message: '请选择菜单类型' }]}
          >
            <Select
              options={[
                { label: '目录', value: 'directory' },
                { label: '菜单', value: 'menu' },
                { label: '按钮', value: 'button' },
              ]}
            />
          </Form.Item>
          <Form.Item name="sort_order" label="排序" initialValue={0}>
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="visible" label="可见" valuePropName="checked" initialValue>
            <Switch />
          </Form.Item>
          <Form.Item name="permission" label="权限标识">
            <Input placeholder="如 system:user:list" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
