import { useState, type FormEvent } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Building2, KeyRound, Pencil, Plus, Shield, Unlock, Users, CheckCircle2, XCircle, ShieldCheck } from 'lucide-react'
import { toast } from 'sonner'
import { PageHeader } from '@/components/PageHeader'
import { DataTable, Pagination, type Column } from '@/components/DataTable'
import { PermissionGuard } from '@/components/PermissionGuard'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { Label } from '@/components/ui/Label'
import { Select } from '@/components/ui/Select'
import { Dialog } from '@/components/ui/Dialog'
import { api } from '@/lib/api'
import { getErrorMessage } from '@/lib/apiError'
import { MenuKeys } from '@/lib/menuKeys'
import type { Department, Paged } from '@/types/master'
import { AVAILABLE_ROLES, RoleShortName, RoleLabel, type User } from '@/types/users'

const fmtDate = (s: string) => new Date(s).toLocaleDateString('vi-VN')

type CreateForm = {
  email: string
  fullName: string
  password: string
  roles: string[]
  departmentId: string
  position: string
}
type EditForm = {
  id: string
  fullName: string
  isActive: boolean
  departmentId: string
  position: string
}

const emptyCreate: CreateForm = { email: '', fullName: '', password: '', roles: [], departmentId: '', position: '' }

export function UsersPage() {
  const qc = useQueryClient()
  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')

  const [createOpen, setCreateOpen] = useState(false)
  const [createForm, setCreateForm] = useState<CreateForm>(emptyCreate)

  const [editForm, setEditForm] = useState<EditForm | null>(null)

  const [rolesModal, setRolesModal] = useState<User | null>(null)
  const [roleSelection, setRoleSelection] = useState<string[]>([])

  const [resetModal, setResetModal] = useState<User | null>(null)
  const [newPassword, setNewPassword] = useState('')

  const list = useQuery({
    queryKey: ['users', { page, search }],
    queryFn: async () =>
      (await api.get<Paged<User>>('/users', { params: { page, pageSize: 20, search: search || undefined } })).data,
  })

  const departments = useQuery({
    queryKey: ['departments-all'],
    queryFn: async () => (await api.get<Paged<Department>>('/departments', { params: { page: 1, pageSize: 200 } })).data.items,
  })

  const createMut = useMutation({
    mutationFn: async () => {
      await api.post('/users', {
        email: createForm.email,
        fullName: createForm.fullName,
        password: createForm.password,
        roles: createForm.roles,
        departmentId: createForm.departmentId || null,
        position: createForm.position || null,
      })
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã tạo user')
      setCreateOpen(false)
      setCreateForm(emptyCreate)
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const editMut = useMutation({
    mutationFn: async () => {
      if (!editForm) return
      await api.put(`/users/${editForm.id}`, {
        id: editForm.id,
        fullName: editForm.fullName,
        isActive: editForm.isActive,
        departmentId: editForm.departmentId || null,
        position: editForm.position || null,
      })
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã lưu')
      setEditForm(null)
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const rolesMut = useMutation({
    mutationFn: async () => {
      if (!rolesModal) return
      await api.put(`/users/${rolesModal.id}/roles`, { roles: roleSelection })
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã cập nhật role')
      setRolesModal(null)
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const resetMut = useMutation({
    mutationFn: async () => {
      if (!resetModal) return
      await api.post(`/users/${resetModal.id}/reset-password`, { newPassword })
    },
    onSuccess: () => {
      toast.success(`Đã reset password. User phải login lại.`)
      setResetModal(null)
      setNewPassword('')
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const unlockMut = useMutation({
    mutationFn: (id: string) => api.post(`/users/${id}/unlock`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã mở khóa')
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  const toggleActiveMut = useMutation({
    mutationFn: (u: User) =>
      api.put(`/users/${u.id}`, {
        id: u.id, fullName: u.fullName, isActive: !u.isActive,
        departmentId: u.departmentId, position: u.position,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã cập nhật trạng thái')
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  // 2-stage dept approval (Migration 16): bật bypass cho NV → cho phép họ
  // Confirm trực tiếp thay vì chỉ Review. Dùng cho phòng ban không có TPB
  // hoặc TPB ủy quyền cho 1 NV cụ thể.
  const bypassMut = useMutation({
    mutationFn: (u: User) =>
      api.patch(`/users/${u.id}/bypass-review`, { canBypassReview: !u.canBypassReview }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['users'] })
      toast.success('Đã cập nhật quyền bypass review')
    },
    onError: err => toast.error(getErrorMessage(err)),
  })

  function openRoles(u: User) {
    setRolesModal(u)
    setRoleSelection([...u.roles])
  }
  function openEdit(u: User) {
    setEditForm({
      id: u.id, fullName: u.fullName, isActive: u.isActive,
      departmentId: u.departmentId ?? '', position: u.position ?? '',
    })
  }

  function toggleRole(r: string) {
    setRoleSelection(sel => (sel.includes(r) ? sel.filter(x => x !== r) : [...sel, r]))
  }
  function toggleCreateRole(r: string) {
    setCreateForm(f => ({
      ...f,
      roles: f.roles.includes(r) ? f.roles.filter(x => x !== r) : [...f.roles, r],
    }))
  }

  const columns: Column<User>[] = [
    { key: 'email', header: 'Email', render: u => <span className="font-mono text-xs">{u.email}</span> },
    { key: 'fullName', header: 'Họ tên', render: u => u.fullName },
    {
      key: 'departmentName',
      header: 'Phòng ban',
      width: 'w-44',
      render: u => (
        <div className="text-xs">
          <div>{u.departmentName ?? <span className="text-slate-400">—</span>}</div>
          {u.position && <div className="text-slate-500">{u.position}</div>}
        </div>
      ),
    },
    {
      key: 'roles',
      header: 'Vai trò',
      render: u => (
        <div className="flex flex-wrap gap-1">
          {u.roles.length === 0 && <span className="text-xs text-slate-400">—</span>}
          {u.roles.map(r => (
            <span
              key={r}
              className="rounded bg-brand-50 px-1.5 py-0.5 text-xs text-brand-700"
              title={RoleLabel[r] ?? r}
            >
              {RoleShortName[r] ?? r}
            </span>
          ))}
        </div>
      ),
    },
    {
      key: 'isActive',
      header: 'Active',
      width: 'w-20',
      align: 'center',
      render: u =>
        u.isActive ? <CheckCircle2 className="mx-auto h-4 w-4 text-emerald-600" /> : <XCircle className="mx-auto h-4 w-4 text-slate-400" />,
    },
    {
      key: 'isLocked',
      header: 'Locked',
      width: 'w-20',
      align: 'center',
      render: u =>
        u.isLocked ? (
          <span className="inline-flex items-center gap-1 text-xs text-red-600">
            <KeyRound className="h-3.5 w-3.5" />
          </span>
        ) : (
          <span className="text-xs text-slate-400">—</span>
        ),
    },
    {
      key: 'canBypassReview',
      header: 'Bypass',
      width: 'w-20',
      align: 'center',
      render: u =>
        u.canBypassReview ? (
          <span title="NV được Confirm trực tiếp (skip Review)" className="inline-flex items-center gap-1 rounded bg-fuchsia-100 px-1.5 py-0.5 text-[10px] text-fuchsia-700">
            <ShieldCheck className="h-3 w-3" />
            bypass
          </span>
        ) : (
          <span className="text-xs text-slate-400">—</span>
        ),
    },
    { key: 'createdAt', header: 'Ngày tạo', width: 'w-24', render: u => fmtDate(u.createdAt) },
    {
      key: 'actions',
      header: '',
      align: 'right',
      width: 'w-56',
      render: u => (
        <div className="flex justify-end gap-1">
          <PermissionGuard menuKey={MenuKeys.Users} action="Update">
            <Button size="sm" variant="ghost" onClick={() => openEdit(u)} title="Sửa thông tin">
              <Pencil className="h-3.5 w-3.5" />
            </Button>
            <Button size="sm" variant="ghost" onClick={() => openRoles(u)} title="Gán role">
              <Shield className="h-3.5 w-3.5" />
            </Button>
            <Button size="sm" variant="ghost" onClick={() => { setResetModal(u); setNewPassword('') }} title="Reset password">
              <KeyRound className="h-3.5 w-3.5" />
            </Button>
            {u.isLocked && (
              <Button size="sm" variant="ghost" onClick={() => unlockMut.mutate(u.id)} title="Mở khóa">
                <Unlock className="h-3.5 w-3.5 text-amber-600" />
              </Button>
            )}
            <Button
              size="sm"
              variant="ghost"
              onClick={() => bypassMut.mutate(u)}
              title={u.canBypassReview ? 'Tắt bypass (cần Review NV trước)' : 'Bật bypass (NV được Confirm trực tiếp)'}
            >
              <ShieldCheck className={`h-3.5 w-3.5 ${u.canBypassReview ? 'text-fuchsia-600' : 'text-slate-400'}`} />
            </Button>
            <Button size="sm" variant="ghost" onClick={() => toggleActiveMut.mutate(u)} title={u.isActive ? 'Vô hiệu hóa' : 'Kích hoạt'}>
              {u.isActive ? <XCircle className="h-3.5 w-3.5 text-red-500" /> : <CheckCircle2 className="h-3.5 w-3.5 text-emerald-600" />}
            </Button>
          </PermissionGuard>
        </div>
      ),
    },
  ]

  return (
    <div className="p-6">
      <PageHeader
        title={
          <span className="flex items-center gap-2">
            <Users className="h-5 w-5" />
            Người dùng
          </span>
        }
        description="Tạo user + gán phòng ban + gán role để test quyền với non-admin."
        actions={
          <PermissionGuard menuKey={MenuKeys.Users} action="Create">
            <Button onClick={() => setCreateOpen(true)}>
              <Plus className="h-4 w-4" />
              Thêm user
            </Button>
          </PermissionGuard>
        }
      />

      <div className="mb-3 flex gap-2">
        <Input
          placeholder="Tìm email hoặc tên…"
          value={search}
          onChange={e => { setSearch(e.target.value); setPage(1) }}
          className="max-w-sm"
        />
      </div>

      <DataTable columns={columns} rows={list.data?.items ?? []} getRowKey={u => u.id} isLoading={list.isLoading} />
      <Pagination page={page} pageSize={20} total={list.data?.total ?? 0} onChange={setPage} />

      {/* Create user */}
      <Dialog
        open={createOpen}
        onClose={() => setCreateOpen(false)}
        title="Thêm user mới"
        size="md"
        footer={
          <>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>Hủy</Button>
            <Button onClick={(e: FormEvent) => { e.preventDefault(); createMut.mutate() }} disabled={createMut.isPending}>
              {createMut.isPending ? 'Đang tạo…' : 'Tạo'}
            </Button>
          </>
        }
      >
        <form className="space-y-4" onSubmit={e => { e.preventDefault(); createMut.mutate() }}>
          <div className="grid grid-cols-2 gap-3">
            <div className="space-y-1.5">
              <Label>Email *</Label>
              <Input type="email" value={createForm.email} onChange={e => setCreateForm(f => ({ ...f, email: e.target.value }))} required />
            </div>
            <div className="space-y-1.5">
              <Label>Họ tên *</Label>
              <Input value={createForm.fullName} onChange={e => setCreateForm(f => ({ ...f, fullName: e.target.value }))} required />
            </div>
            <div className="space-y-1.5">
              <Label>Phòng ban</Label>
              <Select value={createForm.departmentId} onChange={e => setCreateForm(f => ({ ...f, departmentId: e.target.value }))}>
                <option value="">— Chưa gán —</option>
                {departments.data?.map(d => (
                  <option key={d.id} value={d.id}>{d.code} — {d.name}</option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label>Chức vụ</Label>
              <Input
                value={createForm.position}
                onChange={e => setCreateForm(f => ({ ...f, position: e.target.value }))}
                placeholder="vd: Trưởng phòng CCM"
              />
            </div>
            <div className="col-span-2 space-y-1.5">
              <Label>Password *</Label>
              <Input type="password" value={createForm.password} onChange={e => setCreateForm(f => ({ ...f, password: e.target.value }))} required minLength={8} />
              <div className="text-xs text-slate-500">Tối thiểu 8 ký tự + chữ hoa + thường + số + ký tự đặc biệt</div>
            </div>
          </div>
          <div className="space-y-1.5">
            <Label>Vai trò (Mã — Tên)</Label>
            <div className="grid grid-cols-2 gap-2">
              {AVAILABLE_ROLES.map(r => (
                <label key={r} className="flex cursor-pointer items-center gap-2 rounded border border-slate-200 px-2 py-1 text-xs hover:bg-slate-50">
                  <input
                    type="checkbox"
                    className="accent-brand-600"
                    checked={createForm.roles.includes(r)}
                    onChange={() => toggleCreateRole(r)}
                  />
                  <span className="font-semibold text-slate-700">{RoleShortName[r]}</span>
                  <span className="text-slate-500">— {RoleLabel[r]}</span>
                </label>
              ))}
            </div>
          </div>
        </form>
      </Dialog>

      {/* Edit user info */}
      <Dialog
        open={!!editForm}
        onClose={() => setEditForm(null)}
        title="Sửa thông tin user"
        size="md"
        footer={
          <>
            <Button variant="outline" onClick={() => setEditForm(null)}>Hủy</Button>
            <Button onClick={() => editMut.mutate()} disabled={editMut.isPending}>
              {editMut.isPending ? 'Đang lưu…' : 'Lưu'}
            </Button>
          </>
        }
      >
        {editForm && (
          <div className="grid grid-cols-2 gap-3">
            <div className="col-span-2 space-y-1.5">
              <Label>Họ tên *</Label>
              <Input value={editForm.fullName} onChange={e => setEditForm(f => f && { ...f, fullName: e.target.value })} />
            </div>
            <div className="space-y-1.5">
              <Label>Phòng ban</Label>
              <Select value={editForm.departmentId} onChange={e => setEditForm(f => f && { ...f, departmentId: e.target.value })}>
                <option value="">— Chưa gán —</option>
                {departments.data?.map(d => (
                  <option key={d.id} value={d.id}>{d.code} — {d.name}</option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label>Chức vụ</Label>
              <Input
                value={editForm.position}
                onChange={e => setEditForm(f => f && { ...f, position: e.target.value })}
                placeholder="vd: Trưởng phòng CCM"
              />
            </div>
            <div className="col-span-2 flex items-center gap-2 pt-2">
              <input
                type="checkbox"
                id="edit-active"
                className="h-4 w-4 accent-brand-600"
                checked={editForm.isActive}
                onChange={e => setEditForm(f => f && { ...f, isActive: e.target.checked })}
              />
              <Label htmlFor="edit-active" className="cursor-pointer">Đang kích hoạt</Label>
            </div>
          </div>
        )}
      </Dialog>

      {/* Assign roles */}
      <Dialog
        open={!!rolesModal}
        onClose={() => setRolesModal(null)}
        title={
          <span className="flex items-center gap-2">
            <Building2 className="h-4 w-4" />
            Gán role cho {rolesModal?.fullName}
            {rolesModal?.departmentName && (
              <span className="rounded bg-slate-100 px-2 py-0.5 text-xs text-slate-600">
                {rolesModal.departmentName}
              </span>
            )}
          </span>
        }
        size="md"
        footer={
          <>
            <Button variant="outline" onClick={() => setRolesModal(null)}>Hủy</Button>
            <Button onClick={() => rolesMut.mutate()} disabled={rolesMut.isPending}>
              {rolesMut.isPending ? 'Đang lưu…' : 'Lưu'}
            </Button>
          </>
        }
      >
        <div className="grid grid-cols-2 gap-2">
          {AVAILABLE_ROLES.map(r => (
            <label key={r} className="flex cursor-pointer items-center gap-2 rounded border border-slate-200 px-2 py-1 text-xs hover:bg-slate-50">
              <input
                type="checkbox"
                className="accent-brand-600"
                checked={roleSelection.includes(r)}
                onChange={() => toggleRole(r)}
              />
              <span className="font-semibold text-slate-700">{RoleShortName[r]}</span>
              <span className="text-slate-500">— {RoleLabel[r]}</span>
            </label>
          ))}
        </div>
      </Dialog>

      {/* Reset password */}
      <Dialog
        open={!!resetModal}
        onClose={() => setResetModal(null)}
        title={`Reset password: ${resetModal?.email}`}
        size="sm"
        footer={
          <>
            <Button variant="outline" onClick={() => setResetModal(null)}>Hủy</Button>
            <Button
              variant="danger"
              onClick={() => resetMut.mutate()}
              disabled={resetMut.isPending || newPassword.length < 8}
            >
              {resetMut.isPending ? 'Đang reset…' : 'Reset'}
            </Button>
          </>
        }
      >
        <div className="space-y-3">
          <div className="rounded bg-amber-50 px-3 py-2 text-xs text-amber-800">
            User sẽ bị logout khỏi mọi session + phải login lại với password mới.
          </div>
          <div className="space-y-1.5">
            <Label>Password mới</Label>
            <Input type="password" value={newPassword} onChange={e => setNewPassword(e.target.value)} minLength={8} />
          </div>
        </div>
      </Dialog>
    </div>
  )
}
