import { useEffect, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Plus, Trash2, Copy } from 'lucide-react'
import { api } from '@/lib/api'
import { ListPageShell } from '@/components/ListPageShell'
import { DataTable } from '@/components/DataTable'
import { Pagination } from '@/components/Pagination'
import { SearchBar } from '@/components/SearchBar'
import { Button } from '@/components/Button'
import { Modal } from '@/components/Modal'
import { Field, TextInput, TextArea, Checkbox, MoneyInput } from '@/components/Field'
import { PhoneInput } from '@/components/PhoneInput'
import { useCatalogList, useCatalogMutations } from '@/lib/useCatalog'
import type { PagedResult, RetailPoint } from '@/lib/types'
import type { EmployeeRoleDto } from '@/pages/EmployeeRolesPage'

const URL = '/api/organization/employees'

type EmployeeStatus = 'active' | 'fired' | 'deleted'

interface EmployeeDto {
  id: string
  userId: string | null
  lastName: string
  firstName: string
  middleName: string | null
  position: string | null
  email: string | null
  phone: string | null
  salary: number | null
  taxNumber: string | null
  description: string | null
  imageUrl: string | null
  roleId: string
  roleName: string
  isActive: boolean
  firedAt: string | null
  isDeleted: boolean
  deletedAt: string | null
  status: EmployeeStatus
  retailPointIds: string[]
  /** Главный администратор организации (Organization.AccountOwnerUserId ==
   * Employee.UserId). Любые изменения этой записи (роль, активность,
   * удаление) обычным админам недоступны — только Супер-администратор
   * платформы может это сделать. UI показывает бейдж и блокирует поля. */
  isOwner: boolean
  /** Текущий вошедший пользователь — это сам этот Employee. Нельзя удалить. */
  isSelf: boolean
}

interface Form {
  id?: string
  lastName: string
  firstName: string
  middleName: string
  position: string
  email: string
  phone: string
  /** Денежное значение в валюте организации (берётся из useOrgSettings).
   * Используется MoneyInput, который сам формирует с копейками или без
   * в зависимости от org-setting allowFractionalPrices. */
  salary: number | null
  taxNumber: string
  description: string
  imageUrl: string
  roleId: string
  isActive: boolean
  retailPointIds: string[]
  createAccount: boolean
}

const blankForm = (): Form => ({
  lastName: '', firstName: '', middleName: '', position: '',
  email: '', phone: '',
  salary: null, taxNumber: '', description: '', imageUrl: '',
  roleId: '', isActive: true,
  retailPointIds: [],
  createAccount: true,
})

export function EmployeesPage() {
  const { update, remove } = useCatalogMutations(URL, URL)
  const [form, setForm] = useState<Form | null>(null)
  // Сгенерированный пароль возвращается с сервера один раз — показываем
  // в отдельной модалке, чтобы админ передал сотруднику.
  const [createdAccount, setCreatedAccount] = useState<{ email: string; password: string } | null>(null)
  // Текущий открытый сотрудник — нужен чтобы знать isOwner/isSelf для футера
  // модалки (form содержит только редактируемые поля и не знает про маркеры).
  const [activeEmployee, setActiveEmployee] = useState<EmployeeDto | null>(null)
  // Объяснение почему действие заблокировано — показывается вместо confirm()
  // при попытке удалить главного администратора или себя, либо как обёртка
  // над любой ошибкой 4xx/5xx с сервера.
  const [blockedDelete, setBlockedDelete] = useState<{ title: string; body: string } | null>(null)

  const roles = useQuery({
    queryKey: ['employee-roles-lookup'],
    queryFn: async () => (await api.get<PagedResult<EmployeeRoleDto>>('/api/organization/employee-roles?pageSize=200')).data.items,
    staleTime: 60_000,
  })
  const retailPoints = useQuery({
    queryKey: ['retail-points-lookup'],
    queryFn: async () => (await api.get<PagedResult<RetailPoint>>('/api/catalog/retail-points?pageSize=200')).data.items,
    staleTime: 60_000,
  })

  // Дефолт роли для нового сотрудника — первая по сортировке (Менеджер
  // если есть, иначе Кассир — селект всё равно покажет полный список).
  useEffect(() => {
    if (form && !form.roleId && roles.data?.length) {
      const def = roles.data.find((r) => r.name === 'Менеджер') ?? roles.data[0]
      setForm({ ...form, roleId: def.id })
    }
  }, [form, roles.data])

  const selectedRole = roles.data?.find((r) => r.id === form?.roleId)
  const isCashier = selectedRole?.name === 'Кассир'

  const save = async () => {
    if (!form) return
    const payload = {
      lastName: form.lastName, firstName: form.firstName, middleName: form.middleName || null,
      position: form.position || null, email: form.email || null, phone: form.phone || null,
      salary: form.salary,
      taxNumber: form.taxNumber || null,
      description: form.description || null,
      imageUrl: form.imageUrl || null,
      roleId: form.roleId, isActive: form.isActive,
      retailPointIds: form.retailPointIds,
      createAccount: !form.id && form.createAccount,
    }
    try {
      if (form.id) {
        await update.mutateAsync({ id: form.id, input: payload })
        setForm(null); setActiveEmployee(null)
      } else {
        const res = await api.post<{ employee: EmployeeDto; generatedPassword: string | null }>(URL, payload)
        setForm(null); setActiveEmployee(null)
        // Если сервер вернул password — показываем модалку one-shot.
        if (res.data.generatedPassword && res.data.employee.email) {
          setCreatedAccount({ email: res.data.employee.email, password: res.data.generatedPassword })
        }
      }
    } catch (e) {
      const err = e as { response?: { data?: { error?: string } }, message?: string }
      const msg = err.response?.data?.error ?? err.message ?? 'Не удалось сохранить'
      setBlockedDelete({ title: 'Не удалось сохранить', body: msg })
    }
  }

  const toggleRP = (id: string) => {
    if (!form) return
    const has = form.retailPointIds.includes(id)
    setForm({
      ...form,
      retailPointIds: has ? form.retailPointIds.filter((x) => x !== id) : [...form.retailPointIds, id],
    })
  }

  // Фильтр по статусу сотрудника. По умолчанию показываем только активных
  // и уволенных; «удалённые» — отдельный режим (read-only список архива).
  const [statusFilter, setStatusFilter] = useState<'default' | 'active' | 'fired' | 'deleted' | 'all'>('default')
  const list = useCatalogList<EmployeeDto>(URL, statusFilter === 'default' ? {} : { status: statusFilter })

  return (
    <>
      <ListPageShell
        title="Сотрудники"
        description="Учётные записи и сотрудники без логина. Привязка к ролям, для кассиров — к конкретным кассам."
        actions={
          <>
            <SearchBar value={list.search} onChange={list.setSearch} />
            <select
              value={statusFilter}
              onChange={(e) => setStatusFilter(e.target.value as typeof statusFilter)}
              className="h-9 px-2 rounded-md border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 text-sm"
            >
              <option value="default">Активные и уволенные</option>
              <option value="active">Только активные</option>
              <option value="fired">Только уволенные</option>
              <option value="deleted">Только удалённые</option>
              <option value="all">Все, включая удалённых</option>
            </select>
            <Button onClick={() => setForm(blankForm())}>
              <Plus className="w-4 h-4" /> Добавить сотрудника
            </Button>
          </>
        }
        footer={list.data && list.data.total > 0 && (
          <Pagination page={list.page} pageSize={list.data.pageSize} total={list.data.total} onPageChange={list.setPage} />
        )}
      >
        <DataTable
          rows={list.data?.items ?? []}
          isLoading={list.isLoading}
          rowKey={(r) => r.id}
          sortKey={list.sortKey}
          sortOrder={list.sortOrder}
          onSortChange={list.setSort}
          onRowClick={(r) => {
            setActiveEmployee(r)
            setForm({
              id: r.id, lastName: r.lastName, firstName: r.firstName, middleName: r.middleName ?? '',
              position: r.position ?? '', email: r.email ?? '', phone: r.phone ?? '',
              salary: r.salary,
              taxNumber: r.taxNumber ?? '', description: r.description ?? '', imageUrl: r.imageUrl ?? '',
              roleId: r.roleId, isActive: r.isActive, retailPointIds: r.retailPointIds,
              createAccount: false,
            })
          }}
          columns={[
            { header: 'ФИО', cell: (r) => (
              <div>
                <div className="font-medium flex items-center gap-2">
                  <span className={r.status === 'deleted' ? 'line-through text-slate-400' : ''}>
                    {r.lastName} {r.firstName} {r.middleName ?? ''}
                  </span>
                  {r.status === 'fired' && <span className="text-[10px] text-slate-400">(уволен)</span>}
                  {r.status === 'deleted' && <span className="text-[10px] text-slate-400">(удалён)</span>}
                  {r.isOwner && (
                    <span className="text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300">
                      Главный администратор
                    </span>
                  )}
                </div>
                {r.position && <div className="text-xs text-slate-400">{r.position}</div>}
              </div>
            )},
            { header: 'Роль', width: '160px', cell: (r) => r.roleName },
            { header: 'Email', width: '220px', cell: (r) => r.email ?? '—' },
            { header: 'Телефон', width: '150px', cell: (r) => r.phone ?? '—' },
            { header: 'Учётка', width: '110px', cell: (r) => r.userId
              ? <span className="text-xs text-emerald-600">есть</span>
              : <span className="text-xs text-slate-400">нет</span> },
            { header: 'Статус', width: '110px', cell: (r) => {
              if (r.status === 'deleted') return <span className="text-xs px-1.5 py-0.5 rounded bg-rose-100 text-rose-700 dark:bg-rose-900/30 dark:text-rose-300">Удалён</span>
              if (r.status === 'fired')   return <span className="text-xs px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300">Уволен</span>
              return                         <span className="text-xs px-1.5 py-0.5 rounded bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300">Активен</span>
            }},
          ]}
        />
      </ListPageShell>

      <Modal
        open={!!form}
        onClose={() => { setForm(null); setActiveEmployee(null) }}
        title={form?.id ? 'Редактировать сотрудника' : 'Новый сотрудник'}
        width="max-w-xl"
        footer={
          <>
            {form?.id && activeEmployee && activeEmployee.status !== 'deleted' && (
              <Button
                variant="danger"
                size="sm"
                disabled={activeEmployee.isOwner || activeEmployee.isSelf}
                title={
                  activeEmployee.isOwner
                    ? 'Главного администратора может удалить только Супер-администратор платформы'
                    : activeEmployee.isSelf
                      ? 'Нельзя уволить или удалить себя'
                      : undefined
                }
                onClick={async () => {
                  if (activeEmployee.isOwner) {
                    setBlockedDelete({
                      title: 'Действие заблокировано',
                      body:
                        'Главного администратора организации может изменить или удалить только Супер-администратор платформы. ' +
                        'Чтобы передать роль другому сотруднику или удалить аккаунт — отправьте запрос в поддержку.\n\n' +
                        'Организация не может остаться без главного администратора, поэтому в обычной админке это действие недоступно.',
                    })
                    return
                  }
                  if (activeEmployee.isSelf) {
                    setBlockedDelete({
                      title: 'Нельзя уволить или удалить себя',
                      body:
                        'Свою учётную запись нельзя изменить из этой страницы. ' +
                        'Покинуть организацию можно через Настройки → Аккаунт → Покинуть организацию.',
                    })
                    return
                  }
                  const fullName = `${activeEmployee.lastName ?? ''} ${activeEmployee.firstName ?? ''}`.trim()
                  const confirmText = activeEmployee.status === 'active'
                    ? `Уволить сотрудника «${fullName}»?\n\nЕго учётная запись потеряет доступ, документы и история останутся в системе. Восстановить можно в любой момент.`
                    : `Удалить запись о сотруднике «${fullName}»?\n\nСотрудник уже уволен. После удаления он скрывается из обычных списков, но во всех связанных документах остаётся подпись «${fullName} (удалён)».`
                  if (!confirm(confirmText)) return
                  try {
                    await remove.mutateAsync(form.id!)
                    list.refetch?.()
                    setForm(null); setActiveEmployee(null)
                  } catch (e) {
                    const err = e as { response?: { data?: { error?: string } }, message?: string }
                    const msg = err.response?.data?.error ?? err.message ?? 'Не удалось выполнить операцию'
                    setBlockedDelete({ title: 'Не удалось выполнить', body: msg })
                  }
                }}>
                <Trash2 className="w-4 h-4" />
                {activeEmployee.status === 'active' ? 'Уволить' : 'Удалить'}
              </Button>
            )}
            {form?.id && activeEmployee?.status === 'deleted' && (
              <span className="text-xs text-slate-500 italic">Сотрудник удалён — изменения недоступны.</span>
            )}
            <Button variant="secondary" onClick={() => setForm(null)}>Отмена</Button>
            <Button onClick={save} disabled={!form?.lastName || !form.firstName || !form.roleId}>Сохранить</Button>
          </>
        }
      >
        {form && (
          <div className="space-y-3">
            <div className="grid grid-cols-2 gap-3">
              <Field label="Фамилия *">
                <TextInput value={form.lastName} onChange={(e) => setForm({ ...form, lastName: e.target.value })} />
              </Field>
              <Field label="Имя *">
                <TextInput value={form.firstName} onChange={(e) => setForm({ ...form, firstName: e.target.value })} />
              </Field>
            </div>
            <div className="grid grid-cols-2 gap-3">
              <Field label="Отчество">
                <TextInput value={form.middleName} onChange={(e) => setForm({ ...form, middleName: e.target.value })} />
              </Field>
              <Field label="Должность">
                <TextInput value={form.position} onChange={(e) => setForm({ ...form, position: e.target.value })} placeholder="Кассир, кладовщик…" />
              </Field>
            </div>
            <div className="grid grid-cols-2 gap-3">
              <Field label="Email">
                <TextInput type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
              </Field>
              <Field label="Телефон">
                <PhoneInput value={form.phone} onChange={(v) => setForm({ ...form, phone: v })} />
              </Field>
            </div>
            <div className="grid grid-cols-2 gap-3">
              <Field label="Оклад">
                <MoneyInput value={form.salary} onChange={(v) => setForm({ ...form, salary: v })} />
              </Field>
              <Field label="ИИН">
                <TextInput value={form.taxNumber} onChange={(e) => setForm({ ...form, taxNumber: e.target.value })} placeholder="12 цифр" maxLength={12} inputMode="numeric" />
              </Field>
            </div>
            <Field label="Описание / комментарий">
              <TextArea rows={2} value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
            </Field>
            <div>
              <div className="text-sm font-medium mb-2">Роль *</div>
              {activeEmployee?.isOwner && (
                <p className="text-xs text-amber-700 dark:text-amber-300 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-md px-2.5 py-2 mb-2">
                  Это главный администратор организации — роль фиксирована как «Администратор».
                  Изменить роль может только Супер-администратор платформы.
                </p>
              )}
              <div className={`border border-slate-200 dark:border-slate-700 rounded-md divide-y divide-slate-100 dark:divide-slate-800 max-h-72 overflow-auto ${activeEmployee?.isOwner ? 'opacity-60 pointer-events-none' : ''}`}>
                {/* Системные сначала, потом кастомные. */}
                {roles.data?.slice().sort((a, b) => Number(b.isSystem) - Number(a.isSystem)).map((r) => (
                  <label key={r.id} className="flex items-start gap-2 p-2.5 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/40">
                    <input
                      type="radio"
                      name="role"
                      disabled={activeEmployee?.isOwner}
                      checked={form.roleId === r.id}
                      onChange={() => setForm({ ...form, roleId: r.id })}
                      className="mt-1"
                    />
                    <span className="flex-1 min-w-0">
                      <span className="font-medium">{r.name}</span>
                      {r.isSystem && <span className="ml-2 text-xs px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800">системная</span>}
                      {r.description && <div className="text-xs text-slate-500 mt-0.5">{r.description}</div>}
                    </span>
                  </label>
                ))}
              </div>
              <a href="/settings/employee-roles" className="text-xs text-[var(--color-brand)] hover:underline mt-1.5 inline-block">
                Настроить права ролей →
              </a>
            </div>
            {isCashier && (
              <div>
                <div className="text-sm font-medium mb-1.5">Кассы</div>
                <div className="border border-slate-200 dark:border-slate-700 rounded-md p-2 max-h-40 overflow-auto space-y-1">
                  {retailPoints.data?.length === 0 && (
                    <div className="text-xs text-slate-400">Нет касс. Добавь в Настройках.</div>
                  )}
                  {retailPoints.data?.map((rp) => (
                    <Checkbox
                      key={rp.id}
                      label={rp.name}
                      checked={form.retailPointIds.includes(rp.id)}
                      onChange={() => toggleRP(rp.id)}
                    />
                  ))}
                </div>
                <p className="text-xs text-slate-500 mt-1">Если ничего не выбрано — кассир работает на всех кассах.</p>
              </div>
            )}
            <Checkbox
              label="Активен"
              checked={form.isActive}
              disabled={activeEmployee?.isOwner}
              onChange={(v) => setForm({ ...form, isActive: v })}
            />
            {activeEmployee?.isOwner && (
              <p className="text-xs text-slate-500 -mt-1">
                Главного администратора нельзя деактивировать в обычной админке.
                Это действие выполняет Супер-администратор платформы.
              </p>
            )}
            {!form.id && (
              <Checkbox
                label="Создать учётную запись (выдать логин)"
                checked={form.createAccount}
                onChange={(v) => setForm({ ...form, createAccount: v })}
              />
            )}
            {!form.id && form.createAccount && !form.email && (
              <p className="text-xs text-amber-600">Для создания учётки укажи email — он будет логином.</p>
            )}
          </div>
        )}
      </Modal>

      <Modal
        open={!!createdAccount}
        onClose={() => setCreatedAccount(null)}
        title="Учётная запись создана"
        footer={<Button onClick={() => setCreatedAccount(null)}>Готово</Button>}
      >
        {createdAccount && (
          <div className="space-y-3">
            <p className="text-sm text-slate-600 dark:text-slate-300">
              Передайте сотруднику данные для входа. Это окно показывается один раз —
              после закрытия пароль восстановить нельзя, придётся сбросить.
            </p>
            <Field label="Логин (email)">
              <div className="flex gap-2">
                <TextInput value={createdAccount.email} readOnly />
                <Button variant="secondary" size="sm" onClick={() => navigator.clipboard?.writeText(createdAccount.email)}>
                  <Copy className="w-4 h-4" />
                </Button>
              </div>
            </Field>
            <Field label="Временный пароль">
              <div className="flex gap-2">
                <TextInput value={createdAccount.password} readOnly className="font-mono" />
                <Button variant="secondary" size="sm" onClick={() => navigator.clipboard?.writeText(createdAccount.password)}>
                  <Copy className="w-4 h-4" />
                </Button>
              </div>
            </Field>
          </div>
        )}
      </Modal>

      <Modal
        open={!!blockedDelete}
        onClose={() => setBlockedDelete(null)}
        title={blockedDelete?.title ?? ''}
        width="max-w-md"
        footer={
          <Button onClick={() => setBlockedDelete(null)}>Понятно</Button>
        }
      >
        <p className="text-sm text-slate-700 dark:text-slate-200 whitespace-pre-line">
          {blockedDelete?.body}
        </p>
      </Modal>
    </>
  )
}
