import { DownOutlined, PlusOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons'
import {
  Alert,
  App,
  Button,
  Card,
  Dropdown,
  Empty,
  Form,
  Input,
  Result,
  Select,
  Space,
  Table,
  Tag,
  Typography,
} from 'antd'
import type { MenuProps, TableColumnsType } from 'antd'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { useMemo, useState } from 'react'
import { useSearchParams } from 'react-router'

import PageHeader from '@/components/admin/PageHeader'
import StatusTag from '@/components/admin/StatusTag'
import {
  createAdminUser,
  fetchAdminRolePermissions,
  fetchAdminUsers,
  resetAdminUserPassword,
  updateAdminUserRole,
  updateAdminUserStatus,
  updateAdminRolePermissions,
} from '@/services/admin'
import type { AdminRole, AdminUserListItem } from '@/types/admin'
import { getAdminUserId, hasAdminRole } from '@/utils/admin-auth'
import { adminUserRoleOptions, adminUserStatusOptions } from '@/utils/admin-options'
import {
  ADMIN_DEFAULT_PAGE_SIZE,
  buildAdminTablePagination,
  resolveAdminPageSize,
} from '@/utils/admin-pagination'
import { formatAdminDateTime } from '@/utils/admin-time'

type UserFilterForm = {
  username?: string
  role?: string
  status?: string
}

type CreateUserForm = {
  username: string
  password: string
  role: AdminRole
}

const USER_ROLE_OPTIONS = [
  { label: '普通运营', value: 'operator' },
  { label: '客服', value: 'support' },
  { label: '财务', value: 'finance' },
  { label: '管理员', value: 'admin' },
]

export default function AdminUsersPage() {
  const isAdmin = hasAdminRole('admin')
  const currentUserId = getAdminUserId()
  const queryClient = useQueryClient()
  const { message, modal } = App.useApp()
  const [searchParams, setSearchParams] = useSearchParams()
  const [createForm] = Form.useForm<CreateUserForm>()
  const [creating, setCreating] = useState(false)
  const [actionLoadingId, setActionLoadingId] = useState<number | null>(null)
  const page = Number(searchParams.get('page') || 1) || 1
  const pageSize = resolveAdminPageSize(searchParams.get('pageSize'), ADMIN_DEFAULT_PAGE_SIZE)
  const filters = {
    username: searchParams.get('username') || '',
    role: searchParams.get('role') || '',
    status: searchParams.get('status') || '',
  }
  const queryParams = useMemo(
    () => ({ page, pageSize, ...filters }),
    [filters.role, filters.status, filters.username, page, pageSize],
  )
  const query = useQuery({
    queryKey: ['admin-users', queryParams],
    enabled: isAdmin,
    queryFn: () => fetchAdminUsers(queryParams),
  })
  const data = query.data?.data
  const rolePermissionsQuery = useQuery({
    queryKey: ['admin-role-permissions'],
    enabled: isAdmin,
    queryFn: () => fetchAdminRolePermissions(),
  })

  async function reloadUsers() {
    await queryClient.invalidateQueries({ queryKey: ['admin-users'] })
  }

  async function toggleRolePermission(roleKey: string, permissionKey: string, enabled: boolean) {
    const role = rolePermissionsQuery.data?.data.roles.find((item) => item.roleKey === roleKey)
    if (!role || roleKey === 'admin') return
    const permissions = role.permissions
      .filter((item) => item.enabled)
      .map((item) => item.permissionKey)
      .filter((item) => item !== permissionKey)
    if (enabled) permissions.push(permissionKey)
    try {
      await updateAdminRolePermissions(roleKey, permissions)
      await queryClient.invalidateQueries({ queryKey: ['admin-role-permissions'] })
      message.success('角色权限已更新')
    } catch (error) {
      message.error(error instanceof Error ? error.message : '更新角色权限失败')
    }
  }

  async function submitCreate(values: CreateUserForm) {
    setCreating(true)

    try {
      await createAdminUser({
        username: values.username.trim(),
        password: values.password.trim(),
        role: values.role,
        status: 'active',
      })
      message.success('后台用户已创建')
      createForm.resetFields()
      setSearchParams(cleanParams({ ...filters, page: 1, pageSize }))
      await reloadUsers()
    } catch (error) {
      message.error(error instanceof Error ? error.message : '创建后台用户失败')
    } finally {
      setCreating(false)
    }
  }

  function confirmUpdateRole(item: AdminUserListItem, nextRole: AdminRole) {
    if (item.role === nextRole) return

    modal.confirm({
      title: '确认操作',
      content: `确认将 ${item.username} 调整为${formatRoleLabel(nextRole)}吗？`,
      okText: '继续执行',
      cancelText: '取消',
      centered: true,
      onOk: async () => {
        setActionLoadingId(item.userId)
        try {
          await updateAdminUserRole(item.userId, { role: nextRole })
          message.success('用户角色已更新')
          await reloadUsers()
        } catch (error) {
          message.error(error instanceof Error ? error.message : '更新用户角色失败')
        } finally {
          setActionLoadingId(null)
        }
      },
    })
  }

  function confirmToggleStatus(item: AdminUserListItem) {
    const nextStatus = item.status === 'active' ? 'disabled' : 'active'

    modal.confirm({
      title: '确认操作',
      content: `确认将 ${item.username}${nextStatus === 'active' ? '启用' : '停用'}吗？`,
      okText: '继续执行',
      cancelText: '取消',
      centered: true,
      onOk: async () => {
        setActionLoadingId(item.userId)
        try {
          await updateAdminUserStatus(item.userId, { status: nextStatus })
          message.success('用户状态已更新')
          await reloadUsers()
        } catch (error) {
          message.error(error instanceof Error ? error.message : '更新用户状态失败')
        } finally {
          setActionLoadingId(null)
        }
      },
    })
  }

  function openResetPasswordModal(item: AdminUserListItem) {
    const form = ModalFormStore.create<{ password: string }>()

    modal.confirm({
      title: '重置密码',
      content: (
        <Form
          layout="vertical"
          preserve={false}
          initialValues={{ password: '' }}
          ref={form.bind}
          className="modal-form"
        >
          <Form.Item
            name="password"
            label={`请输入 ${item.username} 的新密码`}
            rules={[
              { required: true, message: '请输入新密码' },
              { min: 8, message: '密码至少 8 位' },
            ]}
          >
            <Input.Password placeholder="至少 8 位" />
          </Form.Item>
        </Form>
      ),
      okText: '提交',
      cancelText: '取消',
      centered: true,
      onOk: async () => {
        const values = await form.validate()
        setActionLoadingId(item.userId)
        try {
          await resetAdminUserPassword(item.userId, { password: values.password.trim() })
          message.success('用户密码已重置')
          await reloadUsers()
        } catch (error) {
          message.error(error instanceof Error ? error.message : '重置密码失败')
        } finally {
          setActionLoadingId(null)
        }
      },
    })
  }

  function applyFilters(values: UserFilterForm) {
    setSearchParams(cleanParams({ ...values, page: 1, pageSize }))
  }

  function resetFilters() {
    setSearchParams(cleanParams({ page: 1, pageSize }))
  }

  if (!isAdmin) {
    return (
      <section className="page-stack">
        <PageHeader title="后台用户" description="管理员可维护后台账号、角色和启停状态。" />
        <Result status="warning" title="仅管理员可以访问用户管理。" />
      </section>
    )
  }

  const columns: TableColumnsType<AdminUserListItem> = [
    {
      title: 'ID',
      dataIndex: 'userId',
      width: 72,
      align: 'center',
    },
    {
      title: '账号',
      dataIndex: 'username',
      minWidth: 150,
      render: (value, row) => (
        <Space>
          <Typography.Text strong>{value}</Typography.Text>
          {row.userId === currentUserId ? <Tag>当前账号</Tag> : null}
        </Space>
      ),
    },
    {
      title: '角色',
      dataIndex: 'role',
      width: 120,
      render: (value: AdminRole) => formatRoleLabel(value),
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 140,
      render: (value) => <StatusTag value={value} />,
    },
    {
      title: '创建时间',
      dataIndex: 'createdAt',
      width: 170,
      render: (value) => formatAdminDateTime(value),
    },
    {
      title: '更新时间',
      dataIndex: 'updatedAt',
      width: 170,
      render: (value) => formatAdminDateTime(value),
    },
    {
      title: '操作',
      width: 310,
      render: (_, row) => {
        const isCurrent = row.userId === currentUserId
        const roleMenuItems: MenuProps['items'] = USER_ROLE_OPTIONS.map((item) => ({
          key: item.value,
          label: `设为${item.label}`,
          disabled: row.role === item.value,
        }))

        return (
          <Space wrap>
            <Dropdown
              disabled={isCurrent}
              menu={{
                items: roleMenuItems,
                onClick: ({ key }) => confirmUpdateRole(row, key as AdminRole),
              }}
            >
              <Button disabled={isCurrent} loading={actionLoadingId === row.userId}>
                改角色 <DownOutlined />
              </Button>
            </Dropdown>
            <Button
              disabled={isCurrent}
              loading={actionLoadingId === row.userId}
              onClick={() => confirmToggleStatus(row)}
            >
              {row.status === 'active' ? '停用' : '启用'}
            </Button>
            <Button
              type="primary"
              loading={actionLoadingId === row.userId}
              onClick={() => openResetPasswordModal(row)}
            >
              重置密码
            </Button>
          </Space>
        )
      },
    },
  ]

  return (
    <section className="page-stack">
      <PageHeader
        title="后台用户"
        description="管理员可维护后台账号、角色和启停状态，避免继续使用单一口令。"
      />

      <Card className="users-action-card">
        <div className="users-action-row">
          <section className="users-action-section">
            <div className="users-action-title">筛选用户</div>
            <Form<UserFilterForm>
              layout="inline"
              initialValues={filters}
              onFinish={applyFilters}
              className="filter-form users-action-form"
            >
              <Form.Item name="username">
                <Input allowClear placeholder="账号筛选" className="users-input-md" />
              </Form.Item>
              <Form.Item name="role">
                <Select
                  allowClear
                  placeholder="角色"
                  options={adminUserRoleOptions}
                  className="users-select-sm"
                />
              </Form.Item>
              <Form.Item name="status">
                <Select
                  allowClear
                  placeholder="状态"
                  options={adminUserStatusOptions}
                  className="users-select-sm"
                />
              </Form.Item>
              <Form.Item>
                <Space>
                  <Button type="primary" icon={<SearchOutlined />} htmlType="submit">
                    查询
                  </Button>
                  <Button icon={<ReloadOutlined />} onClick={resetFilters}>
                    重置
                  </Button>
                </Space>
              </Form.Item>
            </Form>
          </section>

          <section className="users-action-section">
            <div className="users-action-title">新增用户</div>
            <Form<CreateUserForm>
              form={createForm}
              layout="inline"
              initialValues={{ role: 'operator' }}
              onFinish={submitCreate}
              className="filter-form users-action-form"
            >
              <Form.Item name="username" rules={[{ required: true, message: '请输入新账号' }]}>
                <Input placeholder="新账号" className="users-input-md" />
              </Form.Item>
              <Form.Item
                name="password"
                rules={[
                  { required: true, message: '请输入新密码' },
                  { min: 8, message: '密码至少 8 位' },
                ]}
              >
                <Input.Password placeholder="新密码，至少 8 位" className="users-input-lg" />
              </Form.Item>
              <Form.Item name="role" rules={[{ required: true, message: '请选择角色' }]}>
                <Select options={USER_ROLE_OPTIONS} className="users-select-sm" />
              </Form.Item>
              <Form.Item>
                <Button type="primary" htmlType="submit" icon={<PlusOutlined />} loading={creating}>
                  新增用户
                </Button>
              </Form.Item>
            </Form>
          </section>
        </div>
      </Card>

      {query.error ? (
        <Alert
          type="error"
          showIcon
          message={query.error instanceof Error ? query.error.message : '读取后台用户失败'}
        />
      ) : null}

      <Card
        title="用户列表"
        extra={
          <Typography.Text type="secondary">
            共 {data?.pagination.total || 0} 个账号
          </Typography.Text>
        }
      >
        <Table<AdminUserListItem>
          rowKey="userId"
          loading={query.isLoading || query.isFetching}
          columns={columns}
          dataSource={data?.items || []}
          locale={{ emptyText: <Empty description="暂无用户" /> }}
          scroll={{ x: 1060 }}
          pagination={buildAdminTablePagination({
            current: data?.pagination.page || page,
            pageSize: data?.pagination.pageSize || pageSize,
            total: data?.pagination.total || 0,
            onChange: (nextPage, nextPageSize) => {
              setSearchParams(cleanParams({ ...filters, page: nextPage, pageSize: nextPageSize }))
            },
          })}
        />
      </Card>

      <Card title="角色权限">
        <Space direction="vertical" size="middle" style={{ width: '100%' }}>
          {(rolePermissionsQuery.data?.data.roles || []).map((role) => (
            <div key={role.roleKey}>
              <Typography.Text strong>{role.roleName}</Typography.Text>
              <div style={{ marginTop: 8 }}>
                <Space wrap>
                  {role.permissions.map((permission) => (
                    <Button
                      key={permission.permissionKey}
                      size="small"
                      type={permission.enabled ? 'primary' : 'default'}
                      disabled={role.roleKey === 'admin'}
                      onClick={() =>
                        void toggleRolePermission(
                          role.roleKey,
                          permission.permissionKey,
                          !permission.enabled,
                        )
                      }
                    >
                      {permission.permissionName}
                    </Button>
                  ))}
                </Space>
              </div>
            </div>
          ))}
        </Space>
      </Card>
    </section>
  )
}

function formatRoleLabel(role: AdminRole) {
  if (role === 'admin') return '管理员'
  if (role === 'support') return '客服'
  if (role === 'finance') return '财务'
  return '普通运营'
}

function cleanParams(params: Record<string, unknown>) {
  const next = new URLSearchParams()
  Object.entries(params).forEach(([key, value]) => {
    const normalized = String(value ?? '').trim()
    if (normalized) {
      next.set(key, normalized)
    }
  })
  return next
}

class ModalFormStore<T extends object> {
  private form: ReturnType<typeof Form.useForm<T>>[0] | null = null

  static create<T extends object>() {
    return new ModalFormStore<T>()
  }

  bind = (instance: unknown) => {
    this.form = instance as ReturnType<typeof Form.useForm<T>>[0] | null
  }

  async validate(): Promise<T> {
    if (!this.form) {
      return {} as T
    }

    return this.form.validateFields()
  }
}
