import { useEffect, useState } from 'react'
import { Button, Dialog, FormField, FormGrid, Notice, useToast } from '@sims/ui'
import { createClient, patchClient, type Client, type ClientContact } from '../api'

interface ContactDraft { name: string; email: string; phone: string; role: string }
const EMPTY_CONTACT: ContactDraft = { name: '', email: '', phone: '', role: '' }

/** Create/edit a client — identity, address, notes, and the contacts repeater. */
export function ClientFormDialog(props: {
  open: boolean
  onClose: () => void
  initial?: Client
  onSaved: (c: Client) => void
}) {
  const toast = useToast()
  const editing = props.initial !== undefined
  const [f, setF] = useState({
    name: '', gstin: '', stateCode: '32', address: '', notes: '',
    anydesk: '', os: '', district: '', sector: '',
  })
  const [contacts, setContacts] = useState<ContactDraft[]>([])
  const [error, setError] = useState<string | undefined>()
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (!props.open) return
    const c = props.initial
    setError(undefined)
    setF({
      name: c?.name ?? '', gstin: c?.gstin ?? '', stateCode: c?.stateCode ?? '32',
      address: c?.address ?? '', notes: c?.notes ?? '',
      anydesk: c?.anydesk ?? '', os: c?.os ?? '', district: c?.district ?? '', sector: c?.sector ?? '',
    })
    setContacts((c?.contacts ?? []).map((ct) => ({
      name: ct.name, email: ct.email ?? '', phone: ct.phone ?? '', role: ct.role ?? '',
    })))
  }, [props.open, props.initial])

  const set = (k: keyof typeof f) => (e: { target: { value: string } }) =>
    setF((p) => ({ ...p, [k]: e.target.value }))
  const setContact = (i: number, k: keyof ContactDraft) => (e: { target: { value: string } }) =>
    setContacts((prev) => prev.map((c, j) => (j === i ? { ...c, [k]: e.target.value } : c)))

  const save = () => {
    if (saving) return
    if (f.name.trim() === '') { setError('Name is required'); return }
    if (!/^\d{2}$/.test(f.stateCode.trim())) { setError('State code must be two digits'); return }
    const cleaned: ClientContact[] = contacts
      .filter((c) => c.name.trim() !== '' || c.email.trim() !== '' || c.phone.trim() !== '')
      .map((c) => ({
        name: c.name.trim() !== '' ? c.name.trim() : (c.email.trim() !== '' ? c.email.trim() : c.phone.trim()),
        ...(c.email.trim() !== '' ? { email: c.email.trim() } : {}),
        ...(c.phone.trim() !== '' ? { phone: c.phone.trim() } : {}),
        ...(c.role.trim() !== '' ? { role: c.role.trim() } : {}),
      }))
    const gstin = f.gstin.trim()
    const body = {
      name: f.name.trim(), stateCode: f.stateCode.trim(),
      address: f.address, notes: f.notes, contacts: cleaned,
      // Support-access fields (D18 WS-F). PATCH clears on ''; POST omits blanks.
      ...(editing
        ? { anydesk: f.anydesk, os: f.os, district: f.district, sector: f.sector }
        : {
            ...(f.anydesk.trim() !== '' ? { anydesk: f.anydesk.trim() } : {}),
            ...(f.os.trim() !== '' ? { os: f.os.trim() } : {}),
            ...(f.district.trim() !== '' ? { district: f.district.trim() } : {}),
            ...(f.sector.trim() !== '' ? { sector: f.sector.trim() } : {}),
          }),
      // Server quirk: PATCH accepts gstin: null to clear (repos-clients skips the checksum
      // assert on null), but POST's ClientInput.gstin is a bare optional string — sending
      // null there crashes assertGstin's .toUpperCase() on null. So: editing may clear via
      // null; creating omits the key entirely when blank.
      ...(editing
        ? { gstin: gstin === '' ? null : gstin.toUpperCase() }
        : (gstin !== '' ? { gstin: gstin.toUpperCase() } : {})),
    }
    setError(undefined)
    setSaving(true)
    const call = editing ? patchClient(props.initial!.id, body) : createClient(body)
    call
      .then((c) => { toast.ok(editing ? 'Client saved' : `Client ${c.code} created`); props.onSaved(c); props.onClose() })
      .catch((e: Error) => setError(e.message))
      .finally(() => setSaving(false))
  }

  return (
    <Dialog
      open={props.open}
      onClose={() => { if (!saving) props.onClose() }}
      title={editing ? `Edit ${props.initial!.name}` : 'New client'}
      size="lg"
      footer={
        <>
          <Button pill onClick={() => { if (!saving) props.onClose() }}>Cancel</Button>
          <Button pill tone="primary" disabled={saving} onClick={save}>{saving ? 'Saving…' : editing ? 'Save changes' : 'Create client'}</Button>
        </>
      }
    >
      <FormGrid>
        <FormField label="Name" wide><input className="wf" autoFocus value={f.name} onChange={set('name')} /></FormField>
        <FormField label="GSTIN (optional)"><input className="wf mono" value={f.gstin} onChange={set('gstin')} /></FormField>
        <FormField label="State code"><input className="wf" style={{ width: 80 }} value={f.stateCode} onChange={set('stateCode')} /></FormField>
        <FormField label="Address" wide><textarea className="wf" rows={2} value={f.address} onChange={set('address')} /></FormField>
        <FormField label="District"><input className="wf" value={f.district} onChange={set('district')} /></FormField>
        <FormField label="Sector"><input className="wf" value={f.sector} onChange={set('sector')} /></FormField>
        <FormField label="AnyDesk ID"><input className="wf mono" value={f.anydesk} onChange={set('anydesk')} /></FormField>
        <FormField label="OS"><input className="wf" value={f.os} onChange={set('os')} /></FormField>
        <FormField label="Notes" wide><textarea className="wf" rows={2} value={f.notes} onChange={set('notes')} /></FormField>
      </FormGrid>
      <h3 style={{ margin: '14px 0 6px', fontSize: 13 }}>Contacts</h3>
      {contacts.map((c, i) => (
        <div key={i} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
          <input className="wf" placeholder="Name" aria-label="Contact name" value={c.name} onChange={setContact(i, 'name')} />
          <input className="wf" placeholder="Email" aria-label="Contact email" type="email" value={c.email} onChange={setContact(i, 'email')} />
          <input className="wf" placeholder="Phone" aria-label="Contact phone" value={c.phone} onChange={setContact(i, 'phone')} />
          {/* Typed roles (D18 WS-F): whatsapp/secretary get labeled rows on the support card; free text stays allowed. */}
          <input className="wf" placeholder="Role" aria-label="Contact role" list="hq-contact-roles" style={{ maxWidth: 110 }} value={c.role} onChange={setContact(i, 'role')} />
          <Button aria-label="Remove contact" onClick={() => setContacts((prev) => prev.filter((_x, j) => j !== i))}>✕</Button>
        </div>
      ))}
      <datalist id="hq-contact-roles">
        <option value="whatsapp" />
        <option value="secretary" />
      </datalist>
      <Button onClick={() => setContacts((prev) => [...prev, { ...EMPTY_CONTACT }])}>+ Add contact</Button>
      {error !== undefined && <Notice tone="err">{error}</Notice>}
    </Dialog>
  )
}
