import React, { useEffect, useMemo, useState } from 'react'
import { Button, Form, Input, Modal, Popconfirm, Select, Space, Table, Tag, Typography, message, TreeSelect } from 'antd'
import api from '../utils/axios'
import type { ColumnsType } from 'antd/es/table'
import { formatDateTime } from '../utils/datetime'
import { EditOutlined, DeleteOutlined, KeyOutlined, UserOutlined } from '@ant-design/icons'
import { usePermission } from '../utils/permission'
import PageHeader from '../components/PageHeader'

interface UserItem {
  id: number
  username: string
  nickname?: string
  status?: number
  created_at?: string
}

// 简单的 {id, name} 类型守卫，便于从未知数组安全映射
type IdName = { id: number; name: string }
const isIdName = (o: unknown): o is IdName => {
  if (typeof o !== 'object' || o === null) return false
  const rec = o as Record<string, unknown>
  return typeof rec.id === 'number' && typeof rec.name === 'string'
}

// 部门基础类型与守卫（包含 parent_id 便于构建树）
type DeptBasic = { id: number; name: string; parent_id?: number }
const isDeptBasic = (o: unknown): o is DeptBasic => {
  if (typeof o !== 'object' || o === null) return false
  const rec = o as Record<string, unknown>
  const okId = typeof rec.id === 'number'
  const okName = typeof rec.name === 'string'
  const okPid = rec.parent_id === undefined || typeof rec.parent_id === 'number'
  return okId && okName && okPid
}

export default function Users(){
  const [loading, setLoading] = useState(false)
  const [data, setData] = useState([] as UserItem[])
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)
  const [total, setTotal] = useState(0)
  const [keyword, setKeyword] = useState('')

  const [createOpen, setCreateOpen] = useState(false)
  const [editOpen, setEditOpen] = useState(false)
  const [pwdOpen, setPwdOpen] = useState(false)
  const [positionsOpen, setPositionsOpen] = useState(false)
  const [current, setCurrent] = useState(null as UserItem | null)
  const [currentUserId, setCurrentUserId] = useState(null as number | null)
  
  const [form] = Form.useForm()
  const [editForm] = Form.useForm()
  const [pwdForm] = Form.useForm()
  const [searchForm] = Form.useForm()
  
  // 分配角色（移到编辑弹窗内）
  const [selectedRoleIds, setSelectedRoleIds] = useState([] as number[])
  const [allRoles, setAllRoles] = useState([] as { id: number; name: string }[])
  
  // 分配部门（移到编辑弹窗内）
  const [selectedDeptIds, setSelectedDeptIds] = useState([] as number[])
  const [allDepts, setAllDepts] = useState([] as DeptBasic[])
  
  // 岗位分配相关状态
  const [positionOptions, setPositionOptions] = useState([] as { label: string; value: number }[])
  const [userPositions, setUserPositions] = useState([] as number[])
  // 新增/编辑弹窗内的岗位选择
  const [createPositionIds, setCreatePositionIds] = useState([] as number[])
  const [editPositionIds, setEditPositionIds] = useState([] as number[])

  // 权限判断
  const { has } = usePermission()

  // 根据 allDepts 构建部门树（用于选择多个部门）
  type DeptTreeNode = { title: string; value: number; key: number; children?: DeptTreeNode[] }
  const deptTreeData: DeptTreeNode[] = useMemo(() => {
    const map = new Map<number, DeptTreeNode & { children: DeptTreeNode[] }>()
    allDepts.forEach((d: DeptBasic) => map.set(d.id, { title: d.name, value: d.id, key: d.id, children: [] }))
    const roots: (DeptTreeNode & { children: DeptTreeNode[] })[] = []
    allDepts.forEach((d: DeptBasic) => {
      const node = map.get(d.id)!
      if (d.parent_id && map.has(d.parent_id)) {
        const parent = map.get(d.parent_id)
        if (parent) parent.children.push(node)
      } else {
        roots.push(node)
      }
    })
    return roots
  }, [allDepts])

  // 获取岗位选项
  const fetchPositionOptions = async () => {
    try {
      const { data } = await api.get('/positions', { params: { page: 1, page_size: 1000 } })
      if (data?.code === 0) {
        setPositionOptions((data.data.items || []).map((it: any) => ({ label: it.name, value: it.id })))
      }
    } catch (e) {
      console.error('获取岗位列表失败:', e)
    }
  }

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

  const fetchUsers = async (p: number = page, ps: number = pageSize, kw: string = keyword) => {
    setLoading(true)
    try{
      const { data } = await api.get(`/users`, { params: { page: p, page_size: ps, keyword: kw } })
      if(data?.code === 0){
        const resp = data.data
        setData(resp.items || [])
        setTotal(resp.total || 0)
        setPage(resp.page || p)
        setPageSize(resp.page_size || ps)
      }else{
        throw new Error(data?.message || '获取用户失败')
      }
    }catch(e: any){
      message.error(e.message || '获取用户失败')
    }finally{
      setLoading(false)
    }
  }

  useEffect(() => { fetchUsers(1, pageSize, keyword) }, [])

  const onCreate = async () => {
    form.resetFields()
    // 新增用户：预置清空角色与部门选择，并加载候选数据
    setSelectedRoleIds([])
    setSelectedDeptIds([])
    setCreatePositionIds([])
    setCreateOpen(true)
    try {
      await fetchPositionOptions()
      const [rolesRes, deptsRes] = await Promise.all([
        api.get('/roles', { params: { page: 1, page_size: 1000 } }),
        api.get('/departments', { params: { keyword: '' } })
      ])
      if (rolesRes.data?.code === 0) {
        const rolesItemsSrc = Array.isArray(rolesRes.data?.data?.items) ? (rolesRes.data.data.items as unknown[]) : []
        const roleItems = rolesItemsSrc.filter(isIdName).map(({ id, name }) => ({ id, name }))
        setAllRoles(roleItems)
      }
      if (deptsRes.data?.code === 0) {
        const deptsSrc = Array.isArray(deptsRes.data?.data) ? (deptsRes.data.data as unknown[]) : []
        const deptBasics = deptsSrc.filter(isDeptBasic)
        setAllDepts(deptBasics)
      }
    } catch (e: any) {
      message.error(e.message || '加载角色/部门失败')
    }
  }

  const handleCreate = async () => {
    try{
      const values = await form.validateFields()
      const { data } = await api.post('/users', values)
      if(data?.code !== 0){ throw new Error(data?.message || '创建失败') }
      const uid = typeof data?.data?.id === 'number' ? data.data.id : undefined
      if (uid) {
        const [rolesSave, deptsSave, posSave] = await Promise.all([
          api.put(`/users/${uid}/roles`, { ids: selectedRoleIds }),
          api.put(`/users/${uid}/departments`, { ids: selectedDeptIds }),
          api.put(`/users/${uid}/positions`, { ids: createPositionIds })
        ])
        if (rolesSave.data?.code !== 0) throw new Error(rolesSave.data?.message || '保存角色失败')
        if (deptsSave.data?.code !== 0) throw new Error(deptsSave.data?.message || '保存部门失败')
        if (posSave.data?.code !== 0) throw new Error(posSave.data?.message || '保存岗位失败')
      } else {
        message.warning('创建成功，但未获取到用户ID，未能分配角色/部门/岗位')
      }
      message.success('创建成功')
      setCreateOpen(false)
      fetchUsers(1, pageSize)
    }catch(e: any){ if(e?.errorFields) return; message.error(e.message || '创建失败') }
  }

  const onEdit = async (record: UserItem) => {
    setCurrent(record)
    editForm.setFieldsValue({ nickname: record.nickname, status: record.status })
    setEditOpen(true)
    // 加载该用户已分配的角色/部门/岗位及候选列表
    try{
      await fetchPositionOptions()
      const [roleIdsRes, rolesRes, deptIdsRes, deptsRes, posIdsRes] = await Promise.all([
        api.get(`/users/${record.id}/roles`),
        api.get('/roles', { params: { page: 1, page_size: 1000 } }),
        api.get(`/users/${record.id}/departments`),
        api.get('/departments', { params: { keyword: '' } }),
        api.get(`/users/${record.id}/positions`)
      ])
      if(roleIdsRes.data?.code !== 0) throw new Error(roleIdsRes.data?.message || '获取用户角色失败')
      if(rolesRes.data?.code !== 0) throw new Error(rolesRes.data?.message || '获取角色列表失败')
      if(deptIdsRes.data?.code !== 0) throw new Error(deptIdsRes.data?.message || '获取用户部门失败')
      if(deptsRes.data?.code !== 0) throw new Error(deptsRes.data?.message || '获取部门列表失败')
      if(posIdsRes.data?.code !== 0) throw new Error(posIdsRes.data?.message || '获取用户岗位失败')
      const roleIds = Array.isArray(roleIdsRes.data?.data) ? (roleIdsRes.data.data as unknown[]).filter((n): n is number => typeof n === 'number') : []
      setSelectedRoleIds(roleIds)
      const rolesItemsSrc = Array.isArray(rolesRes.data?.data?.items) ? rolesRes.data.data.items as unknown[] : []
      const roleItems = rolesItemsSrc.filter(isIdName).map(({ id, name }) => ({ id, name }))
      setAllRoles(roleItems)
      const deptIds = Array.isArray(deptIdsRes.data?.data) ? (deptIdsRes.data.data as unknown[]).filter((n): n is number => typeof n === 'number') : []
      setSelectedDeptIds(deptIds)
      const deptsSrc = Array.isArray(deptsRes.data?.data) ? (deptsRes.data.data as unknown[]) : []
      const deptBasics = deptsSrc.filter(isDeptBasic)
      setAllDepts(deptBasics)
      const posIds = Array.isArray(posIdsRes.data?.data) ? (posIdsRes.data.data as unknown[]).filter((n): n is number => typeof n === 'number') : []
      setEditPositionIds(posIds)
    }catch(e: any){ message.error(e.message || '加载编辑数据失败') }
  }

  const handleEdit = async () => {
    if(!current) return
    try{
      const values = await editForm.validateFields()
      // 先保存基础信息
      const { data: upd } = await api.put(`/users/${current!.id}`, values)
      if(upd?.code !== 0) throw new Error(upd?.message || '更新失败')
      // 再保存角色与部门
      const [rolesSave, deptsSave] = await Promise.all([
        api.put(`/users/${current.id}/roles`, { ids: selectedRoleIds }),
        api.put(`/users/${current.id}/departments`, { ids: selectedDeptIds }),
        api.put(`/users/${current.id}/positions`, { ids: editPositionIds })
      ])
      if(rolesSave.data?.code !== 0) throw new Error(rolesSave.data?.message || '保存角色失败')
      if(deptsSave.data?.code !== 0) throw new Error(deptsSave.data?.message || '保存部门失败')
      message.success('更新成功')
      setEditOpen(false)
      fetchUsers(page, pageSize)
    }catch(e: any){ if(e?.errorFields) return; message.error(e.message || '更新失败') }
  }

  const onResetPwd = (record: UserItem) => {
    setCurrent(record)
    pwdForm.resetFields()
    setPwdOpen(true)
  }

  const handleResetPwd = async () => {
    try{
      const values = await pwdForm.validateFields()
      const { data } = await api.post(`/users/${current!.id}/reset_password`, values)
      if(data?.code === 0){
        message.success('密码已重置')
        setPwdOpen(false)
      }else{ throw new Error(data?.message || '重置失败') }
    }catch(e: any){ if(e?.errorFields) return; message.error(e.message || '重置失败') }
  }

  // 岗位分配相关方法
  const openPositions = async (userId: number) => {
    setCurrentUserId(userId)
    try {
      const { data } = await api.get(`/users/${userId}/positions`)
      if (data?.code === 0) {
        setUserPositions(data.data || [])
      } else {
        throw new Error(data?.message || '获取用户岗位失败')
      }
    } catch (e: any) {
      message.error(e.message || '获取用户岗位失败')
      setUserPositions([])
    }
    setPositionsOpen(true)
  }

  const savePositions = async () => {
    if (!currentUserId) return
    try {
      const { data } = await api.put(`/users/${currentUserId}/positions`, { ids: userPositions })
      if (data?.code === 0) {
        message.success('岗位分配成功')
        setPositionsOpen(false)
      } else {
        throw new Error(data?.message || '保存岗位失败')
      }
    } catch (e: any) {
      message.error(e.message || '保存岗位失败')
    }
  }

  const columns: ColumnsType<UserItem> = useMemo(() => [
    { title: 'ID', dataIndex: 'id', width: 80 },
    { title: '用户名', dataIndex: 'username' },
    { title: '昵称', dataIndex: 'nickname' },
    { title: '状态', dataIndex: 'status', render: (v: number) => v === 1 ? <Tag color="green">启用</Tag> : <Tag>禁用</Tag> },
    { title: '创建时间', dataIndex: 'created_at', render: (v: any) => formatDateTime(v) },
    { title: '操作', key: 'actions', width: 360, render: (_: any, r: UserItem) => (
      <Space>
        {has('system:user:update') && (
          <a className="action-link" onClick={() => onEdit(r)}>
            <EditOutlined />
            <span>编辑</span>
          </a>
        )}
        {has('system:user:reset') && (
          <a className="action-link" onClick={() => onResetPwd(r)}>
            <KeyOutlined />
            <span>重置密码</span>
          </a>
        )}
        {has('system:user:assignPosition') && (
          <a className="action-link" onClick={() => openPositions(r.id)}>
            <UserOutlined />
            <span>分配岗位</span>
          </a>
        )}
        {has('system:user:delete') && (
          <Popconfirm title={`确认删除用户「${r.username}」？`} onConfirm={async ()=>{ try{ const { data } = await api.delete(`/users/${r.id}`); if(data?.code===0){ message.success('删除成功'); fetchUsers(page, pageSize, keyword) } else { throw new Error(data?.message||'删除失败') } }catch(e:any){ message.error(e.message||'删除失败') } }}>
            <a className="action-link action-danger">
              <DeleteOutlined />
              <span>删除</span>
            </a>
          </Popconfirm>
        )}
      </Space>
    )},
  ], [page, pageSize, keyword, has])

  return (
    <div>
      <PageHeader items={["系统管理","用户管理"]} title="" />
      <Form form={searchForm} layout="inline" onFinish={(vals: any)=>{ const kw = String(vals?.keyword ?? '').trim(); setKeyword(kw); fetchUsers(1, pageSize, kw) }} style={{ marginBottom: 12 }}>
        <Form.Item name="keyword">
          <Input allowClear placeholder="搜索用户名/昵称" style={{ width: 320 }} />
        </Form.Item>
        <Form.Item>
          <Space>
            <Button type="primary" htmlType="submit">搜索</Button>
            <Button onClick={()=>{ searchForm.resetFields(); setKeyword(''); fetchUsers(1, pageSize, '') }}>重置</Button>
            {has('system:user:create') && (
              <Button type="primary" onClick={onCreate}>新增</Button>
            )}
          </Space>
        </Form.Item>
      </Form>
      <Table<UserItem>
        rowKey="id"
        loading={loading}
        dataSource={data}
        columns={columns}
        pagination={{ current: page, pageSize, total, showSizeChanger: true, onChange: (p: number, ps?: number) => fetchUsers(p, ps ?? pageSize, keyword) }}
      />
      <Typography.Paragraph type="secondary" style={{ marginTop: 12 }}>
        提示：此页面已支持分页、创建、编辑与重置密码。
      </Typography.Paragraph>

      <Modal title="新增用户" open={createOpen} onOk={handleCreate} onCancel={() => setCreateOpen(false)} okText="创建" width={840}>
        <Form form={form} layout="horizontal" labelCol={{ span: 2 }} wrapperCol={{ span: 22 }} labelAlign="right">
          <Form.Item name="username" label="用户名" rules={[{ required: true }]}>
            <Input placeholder="请输入用户名" />
          </Form.Item>
          <Form.Item name="password" label="密码" rules={[{ required: true }]}>
            <Input.Password placeholder="请输入密码" />
          </Form.Item>
          <Form.Item name="nickname" label="昵称">
            <Input placeholder="请输入昵称" />
          </Form.Item>
          <Form.Item name="status" label="状态" initialValue={1}>
            <Select options={[{label:'启用', value:1},{label:'禁用', value:0}]} />
          </Form.Item>
          <Form.Item label="角色">
            <Select
              mode="multiple"
              style={{ width: '100%' }}
              placeholder="选择角色"
              value={selectedRoleIds}
              options={allRoles.map((r: { id: number; name: string }) => ({ label: r.name, value: r.id }))}
              onChange={(vals: number[]) => setSelectedRoleIds(vals)}
            />
          </Form.Item>
          <Form.Item label="部门">
            <TreeSelect
              allowClear
              multiple
              treeCheckable
              placeholder="选择部门（支持多选）"
              style={{ width: '100%' }}
              treeData={deptTreeData}
              treeDefaultExpandAll
              showSearch
              filterTreeNode={(input: string, node: any) => String(node?.title ?? '').toLowerCase().includes(String(input).toLowerCase())}
              value={selectedDeptIds}
              onChange={(vals) => setSelectedDeptIds(Array.isArray(vals) ? (vals as (string | number)[]).map(v => Number(v)) : [])}
            />
          </Form.Item>
          {has('system:user:assignPosition') && (
            <Form.Item label="岗位">
              <Select
                mode="multiple"
                allowClear
                placeholder="选择岗位"
                value={createPositionIds}
                options={positionOptions}
                style={{ width: '100%' }}
                onChange={setCreatePositionIds}
              />
            </Form.Item>
          )}
        </Form>
      </Modal>

      <Modal title="编辑用户" open={editOpen} onOk={handleEdit} onCancel={() => setEditOpen(false)} okText="保存" width={840}>
        <Form form={editForm} layout="horizontal" labelCol={{ span: 2 }} wrapperCol={{ span: 22 }} labelAlign="right">
          <Form.Item name="nickname" label="昵称">
            <Input placeholder="请输入昵称" />
          </Form.Item>
          <Form.Item name="status" label="状态">
            <Select options={[{label:'启用', value:1},{label:'禁用', value:0}]} />
          </Form.Item>
          <Form.Item label="角色">
            <Select
              mode="multiple"
              style={{ width: '100%' }}
              placeholder="选择角色"
              value={selectedRoleIds}
              options={allRoles.map((r: { id: number; name: string }) => ({ label: r.name, value: r.id }))}
              onChange={(vals: number[]) => setSelectedRoleIds(vals)}
            />
          </Form.Item>
          <Form.Item label="部门">
            <TreeSelect
              allowClear
              multiple
              treeCheckable
              placeholder="选择部门（支持多选）"
              style={{ width: '100%' }}
              treeData={deptTreeData}
              treeDefaultExpandAll
              showSearch
              filterTreeNode={(input: string, node: any) => String(node?.title ?? '').toLowerCase().includes(String(input).toLowerCase())}
              value={selectedDeptIds}
              onChange={(vals) => setSelectedDeptIds(Array.isArray(vals) ? (vals as (string | number)[]).map(v => Number(v)) : [])}
            />
          </Form.Item>
          {has('system:user:assignPosition') && (
            <Form.Item label="岗位">
              <Select
                mode="multiple"
                allowClear
                placeholder="选择岗位"
                value={editPositionIds}
                options={positionOptions}
                style={{ width: '100%' }}
                onChange={setEditPositionIds}
              />
            </Form.Item>
          )}
        </Form>
      </Modal>

      <Modal title={`重置密码${current ? `（${current.username}）` : ''}`} open={pwdOpen} onOk={handleResetPwd} onCancel={() => setPwdOpen(false)} okText="重置">
        <Form form={pwdForm} layout="vertical">
          <Form.Item name="password" label="新密码" rules={[{ required: true }]}>
            <Input.Password placeholder="请输入新密码" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal title="分配岗位" open={positionsOpen} onOk={savePositions} onCancel={() => setPositionsOpen(false)} okText="保存">
        <Form layout="vertical">
          <Form.Item label="选择岗位">
            <Select
              mode="multiple"
              allowClear
              value={userPositions}
              onChange={setUserPositions}
              options={positionOptions}
              style={{ width: '100%' }}
              placeholder="选择岗位"
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  )
}