import { useState } from 'react'
import { Badge, Button, DataTable, EmptyState, Field, Notice, PageHeader, Toolbar } from '@sims/ui'
import {
  createEmployee, deactivateEmployee, getEmployees, patchEmployee,
  reactivateEmployee, resetEmployeePassword,
  EMPLOYEE_ROLES, type Employee, type EmployeeRole,
} from '../api'
import { useData } from './Clients'

/**
 * Employee management (owner-only page; the nav item is hidden for others and the
 * server 403s every mutation anyway). Standard table per spec §6a: name, email,
 * role, active, actions — plus add / edit / reset-password forms. Email is the
 * login id and is immutable once created.
 */
export function Employees() {
  const list = useData(getEmployees, [])
  const [adding, setAdding] = useState(false)
  const [editing, setEditing] = useState<Employee | undefined>()
  const [resetting, setResetting] = useState<Employee | undefined>()
  const [error, setError] = useState<string | undefined>()

  const act = (p: Promise<unknown>) => {
    setError(undefined)
    p.then(() => list.reload()).catch((e: Error) => setError(e.message))
  }

  const employees = list.data?.employees
  return (
    <div className="wf-page">
      <PageHeader
        title="Employees"
        desc="Console users — owner manages accounts, roles and passwords. Deactivation locks the account out immediately."
        actions={(
          <Button tone="primary" onClick={() => { setAdding((v) => !v); setEditing(undefined); setResetting(undefined) }}>
            + Add employee
          </Button>
        )}
      />
      {adding && (
        <AddEmployeeForm
          onDone={() => { setAdding(false); list.reload() }}
          onCancel={() => setAdding(false)}
        />
      )}
      {editing !== undefined && (
        <EditEmployeeForm
          key={editing.id}
          employee={editing}
          onDone={() => { setEditing(undefined); list.reload() }}
          onCancel={() => setEditing(undefined)}
        />
      )}
      {resetting !== undefined && (
        <ResetPasswordForm
          key={resetting.id}
          employee={resetting}
          onDone={() => { setResetting(undefined); list.reload() }}
          onCancel={() => setResetting(undefined)}
        />
      )}
      {error !== undefined && <Notice tone="err">{error}</Notice>}
      {list.error !== undefined && <Notice tone="err">{list.error}</Notice>}
      {/* Branch on the fetch error first — `employees` stays undefined on failure,
          so falling through would show "Loading…" forever under the error notice. */}
      {list.error !== undefined ? null
        : employees === undefined ? <EmptyState>Loading…</EmptyState>
        : employees.length === 0 ? <EmptyState>No employees yet.</EmptyState> : (
        <>
          <DataTable
            columns={[
              { key: 'name', label: 'Name' }, { key: 'email', label: 'Email' },
              { key: 'role', label: 'Role' }, { key: 'active', label: 'Active' },
              { key: 'actions', label: 'Actions' },
            ]}
            rows={employees.map((e) => ({
              name: e.displayName, email: e.email,
              role: <Badge tone={e.role === 'owner' ? 'accent' : undefined}>{e.role}</Badge>,
              active: e.active ? <Badge tone="ok">active</Badge> : <Badge tone="err">inactive</Badge>,
              actions: (
                <span style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                  <Button onClick={() => { setEditing(e); setAdding(false); setResetting(undefined) }}>Edit</Button>
                  <Button onClick={() => { setResetting(e); setAdding(false); setEditing(undefined) }}>Reset pw</Button>
                  {e.active
                    ? <Button tone="danger" onClick={() => act(deactivateEmployee(e.id))}>Deactivate</Button>
                    : <Button onClick={() => act(reactivateEmployee(e.id))}>Reactivate</Button>}
                </span>
              ),
            }))}
          />
          <Toolbar>
            <Badge>{list.data!.total} employee{list.data!.total === 1 ? '' : 's'}</Badge>
            <span style={{ fontSize: 12, opacity: 0.7 }}>
              Guards: the last active owner cannot be demoted or deactivated; you cannot deactivate yourself.
            </span>
          </Toolbar>
        </>
      )}
    </div>
  )
}

function AddEmployeeForm(props: { onDone: () => void; onCancel: () => void }) {
  const [f, setF] = useState({ email: '', displayName: '', role: 'staff' as EmployeeRole, password: '' })
  const [error, setError] = useState<string | undefined>()
  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))

  const save = () => {
    if (f.email.trim() === '' || f.displayName.trim() === '') { setError('Email and name are required'); return }
    if (f.password.length < 8) { setError('Initial password must be at least 8 characters'); return }
    setError(undefined)
    createEmployee({ email: f.email.trim(), displayName: f.displayName.trim(), role: f.role, password: f.password })
      .then(props.onDone)
      .catch((e: Error) => setError(e.message))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, marginBottom: 12 }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label="Email (login id)"><input className="wf" type="email" autoFocus value={f.email} onChange={set('email')} /></Field>
        <Field label="Name"><input className="wf" value={f.displayName} onChange={set('displayName')} /></Field>
        <Field label="Role">
          <select className="wf" value={f.role} onChange={set('role')}>
            {EMPLOYEE_ROLES.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
        </Field>
        <Field label="Initial password (min 8)"><input className="wf" type="password" value={f.password} onChange={set('password')} /></Field>
        <Button tone="primary" onClick={save}>Create employee</Button>
        <Button onClick={props.onCancel}>Cancel</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}

function EditEmployeeForm(props: { employee: Employee; onDone: () => void; onCancel: () => void }) {
  const [f, setF] = useState({ displayName: props.employee.displayName, role: props.employee.role })
  const [error, setError] = useState<string | undefined>()

  const save = () => {
    if (f.displayName.trim() === '') { setError('Name is required'); return }
    setError(undefined)
    patchEmployee(props.employee.id, { displayName: f.displayName.trim(), role: f.role })
      .then(props.onDone)
      .catch((e: Error) => setError(e.message))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, marginBottom: 12 }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        {/* Email is the login id — immutable after creation. */}
        <Field label="Email (immutable)"><input className="wf" value={props.employee.email} disabled /></Field>
        <Field label="Name">
          <input className="wf" autoFocus value={f.displayName} onChange={(e) => setF((p) => ({ ...p, displayName: e.target.value }))} />
        </Field>
        <Field label="Role">
          <select className="wf" value={f.role} onChange={(e) => setF((p) => ({ ...p, role: e.target.value as EmployeeRole }))}>
            {EMPLOYEE_ROLES.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
        </Field>
        <Button tone="primary" onClick={save}>Save changes</Button>
        <Button onClick={props.onCancel}>Cancel</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}

function ResetPasswordForm(props: { employee: Employee; onDone: () => void; onCancel: () => void }) {
  const [password, setPassword] = useState('')
  const [error, setError] = useState<string | undefined>()

  const save = () => {
    if (password.length < 8) { setError('New password must be at least 8 characters'); return }
    setError(undefined)
    resetEmployeePassword(props.employee.id, password)
      .then(props.onDone)
      .catch((e: Error) => setError(e.message))
  }

  return (
    <div style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 12, marginBottom: 12 }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <Field label={`New password for ${props.employee.email} (min 8)`}>
          <input className="wf" type="password" autoFocus value={password} onChange={(e) => setPassword(e.target.value)} />
        </Field>
        <Button tone="primary" onClick={save}>Reset password</Button>
        <Button onClick={props.onCancel}>Cancel</Button>
      </div>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </div>
  )
}
