/* Create flows: Quick Create hub + full Create Lead / Client / Deal / Activity.
   Specs: lead-card/create-lead.md, client-card/create-client.md, global-navigation §2.8 */
const { useState: useStateForm } = React;

const SOURCE_NAMES = ['Telegram', 'Instagram', 'Referral', 'Cold Call', 'Event', 'Web Form', 'facebook_ads', 'landing_1', 'zapier', 'Other'];
const TAG_SUGGEST = ['enterprise', 'building', 'logistics', 'retail', 'finance', 'trading', 'manufacturing', 'real-estate'];

// Known existing contacts → duplicate trigger (exact email/phone, normalized).
// kind decides the dataset: leads dedup against leads (tenant-wide, all statuses),
// clients dedup against clients — per duplicate-detection.md.
function findDuplicate(email, phone, kind = 'client') {
  const D = window.MonolitData;
  const e = (email || '').toLowerCase().trim();
  const p = (phone || '').replace(/[^\d]/g, '');
  const pool = kind === 'lead' ? D.leads : D.clients;
  const hit = pool.find(c => (e && (c.email || '').toLowerCase() === e) || (p && p.length > 6 && (c.phone || '').replace(/[^\d]/g, '') === p));
  if (!hit) return null;
  const sameTeam = hit.owner && window.MonolitRBAC.TEAM_IDS.includes(hit.owner.id);
  return { record: hit, matchType: e && (hit.email || '').toLowerCase() === e ? (p ? 'both' : 'email') : 'phone', crossTeam: !sameTeam };
}

// ---------- Quick Create hub (+ dropdown) ----------------------------------
function QuickCreateHub({ role, onPick }) {
  const can = window.MonolitRBAC.can;
  const items = [
    { type: 'lead',     icon: 'user-plus',   tt: 'Lead',     sub: 'Potential business', perm: 'leads.create' },
    { type: 'client',   icon: 'building-2',  tt: 'Client',   sub: 'Confirmed contact',  perm: 'clients.create' },
    { type: 'deal',     icon: 'briefcase',   tt: 'Deal',     sub: 'Commercial opportunity', perm: 'deals.create' },
    { type: 'activity', icon: 'plus-square', tt: 'Activity', sub: 'Call / Note / Task', perm: 'activities.create' },
  ].filter(i => can(role, i.perm));
  if (!items.length) return <div style={{ padding: 16, color: 'var(--text-3)', font: 'var(--font-weight-medium) 12px/16px var(--font-sans)' }}>Your role can’t create records.</div>;
  return (
    <React.Fragment>
      <div className="mn-dd-h">Quick create <kbd className="mn-kbd">C</kbd></div>
      <div className="mn-qc-grid">
        {items.map(i => (
          <button key={i.type} type="button" className="mn-qc-item" onClick={() => onPick(i.type)}>
            <span className="mn-qc-item-ico"><Icon name={i.icon} size="sm" /></span>
            <span className="mn-qc-item-tt">{i.tt}</span>
            <span className="mn-qc-item-sub">{i.sub}</span>
          </button>
        ))}
      </div>
      <div className="mn-dd-foot" style={{ color: 'var(--text-3)', font: 'var(--font-weight-medium) 11px/15px var(--font-sans)' }}>
        Minimal form — full fields via “+ New …” in each section.
      </div>
    </React.Fragment>
  );
}

// ---------- Create Lead -----------------------------------------------------
function CreateLeadForm({ mode = 'full', role, onClose, onToast, onOpenRecord, onCreate }) {
  const [f, setF] = useStateForm({ first: '', last: '', email: '', phone: '', company: '', jobTitle: '', country: '', sourceName: '', owner: window.MonolitRBAC.ME, status: 'New', nextStep: '', tags: [], notes: '' });
  const [touched, setTouched] = useStateForm(false);
  const [dup, setDup] = useStateForm(null);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const noChannel = !f.email.trim() && !f.phone.trim();
  const firstErr = f.first.trim().length < 2;
  const valid = !firstErr && !noChannel;

  function save() {
    setTouched(true);
    if (!valid) return;
    const d = findDuplicate(f.email, f.phone, 'lead');
    if (d) { setDup(d); return; }
    const newId = onCreate ? onCreate(f) : null;
    onToast('Lead created · ' + (f.first + ' ' + f.last).trim());
    onClose();
    if (newId && onOpenRecord) onOpenRecord({ kind: 'lead', id: newId });
  }

  const body = (
    <React.Fragment>
      <div className="mn-form-sec">
        <div className="mn-form-sec-h"><span className="num">1</span><span className="mn-form-sec-title">Contact / Identity</span><span className="mn-form-sec-opt">required: name + email or phone</span></div>
        <div className="mn-form-grid">
          <Field label="First name" required error={touched && firstErr ? 'Min. 2 characters' : undefined}>
            <Input fullWidth value={f.first} onChange={(v) => set('first', v)} placeholder="Olena" autoFocus />
          </Field>
          <Field label="Last name"><Input fullWidth value={f.last} onChange={(v) => set('last', v)} placeholder="Pavlenko" /></Field>
          <Field label="Email" required={!f.phone} error={touched && noChannel ? 'Email or phone required' : undefined}>
            <Input fullWidth icon="mail" value={f.email} onChange={(v) => set('email', v)} placeholder="name@company.com" />
          </Field>
          <Field label="Phone" required={!f.email}>
            <Input fullWidth icon="phone" value={f.phone} onChange={(v) => set('phone', v)} placeholder="+44 …" />
          </Field>
        </div>
      </div>

      {mode === 'full' ? (
        <React.Fragment>
          <div className="mn-form-sec">
            <div className="mn-form-sec-h"><span className="num">2</span><span className="mn-form-sec-title">Company / Location</span></div>
            <div className="mn-form-grid">
              <Field label="Company"><Input fullWidth value={f.company} onChange={(v) => set('company', v)} placeholder="Northwind Trading" /></Field>
              <Field label="Job title"><Input fullWidth value={f.jobTitle} onChange={(v) => set('jobTitle', v)} placeholder="Head of Procurement" /></Field>
              <Field label="Country / City" hint="Lead local time derived automatically"><Input fullWidth value={f.country} onChange={(v) => set('country', v)} placeholder="London, UK" /></Field>
              <Field label="Source name"><Select fullWidth value={f.sourceName} onChange={(v) => set('sourceName', v)} options={SOURCE_NAMES} placeholder="Channel…" /></Field>
            </div>
          </div>
          <div className="mn-form-sec">
            <div className="mn-form-sec-h"><span className="num">3</span><span className="mn-form-sec-title">Ownership & status</span></div>
            <div className="mn-form-grid">
              <Field label="Owner" required><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
              <Field label="Status"><Select fullWidth value={f.status} onChange={(v) => set('status', v)} options={['New', 'In Progress']} /></Field>
              <Field label="Next step (optional)"><Input fullWidth icon="flag" value={f.nextStep} onChange={(v) => set('nextStep', v)} placeholder="Send proposal · due date" /></Field>
              <Field label="Source type"><Input fullWidth value="manual" disabled /></Field>
              <div className="mn-col-2"><Field label="Tags"><TagInput tags={f.tags} onChange={(v) => set('tags', v)} suggestions={TAG_SUGGEST} /></Field></div>
              <div className="mn-col-2"><Field label="Notes" hint="Saved as first note activity"><Textarea fullWidth value={f.notes} onChange={(v) => set('notes', v)} maxLength={500} placeholder="First note about this lead…" /></Field></div>
            </div>
          </div>
          <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)' }}>
            BANT scoring isn’t set here — qualify later from the Lead Card. Try email <b>lukas@alpenbau.ch</b> to see duplicate detection.
          </div>
        </React.Fragment>
      ) : (
        <React.Fragment>
          <div className="mn-form-grid" style={{ marginTop: 4 }}>
            <Field label="Owner" required><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
            <Field label="Source type"><Input fullWidth value="manual" disabled /></Field>
          </div>
          <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 8 }}>Minimal form. Full fields via “+ New Lead” in Leads.</div>
        </React.Fragment>
      )}
    </React.Fragment>
  );

  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon="check" onClick={save} disabled={touched && !valid}>Create lead</Button>
  </React.Fragment>;

  const Wrapper = mode === 'full' ? Drawer : Modal;
  const wrapProps = mode === 'full'
    ? { open: true, onClose, width: 560, eyebrow: 'Leads', title: 'New lead', subtitle: 'Full form · deep-linkable /leads/new', footer }
    : { open: true, onClose, eyebrow: 'Quick create', title: 'New lead', size: 'md', footer };

  return (
    <React.Fragment>
      <Wrapper {...wrapProps}>{body}</Wrapper>
      {dup ? <DuplicateModal kind="lead" dup={dup} role={role} onClose={() => setDup(null)}
                onOpenExisting={() => { setDup(null); onClose(); onOpenRecord({ kind: 'lead', id: dup.record.id }); }}
                onCreateAnyway={() => { setDup(null); const id = onCreate ? onCreate(f) : null; onToast('Lead created (duplicate override flagged)'); onClose(); if (id && onOpenRecord) onOpenRecord({ kind: 'lead', id }); }} /> : null}
    </React.Fragment>
  );
}

// ---------- Create Client ---------------------------------------------------
function CreateClientForm({ mode = 'full', role, onClose, onToast, onOpenRecord }) {
  const [f, setF] = useStateForm({ first: '', last: '', email: '', phone: '', account: '', jobTitle: '', country: '', website: '', owner: window.MonolitRBAC.ME, sourceName: '', tags: [], notes: '' });
  const [touched, setTouched] = useStateForm(false);
  const [dup, setDup] = useStateForm(null);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const noChannel = !f.email.trim() && !f.phone.trim();
  const firstErr = f.first.trim().length < 2;
  const valid = !firstErr && !noChannel;

  function save() {
    setTouched(true);
    if (!valid) return;
    const d = findDuplicate(f.email, f.phone);
    if (d) { setDup(d); return; }
    onToast('Client created · ' + f.first + ' ' + f.last);
    onClose();
  }

  const body = (
    <React.Fragment>
      <div className="mn-form-sec">
        <div className="mn-form-sec-h"><span className="num">1</span><span className="mn-form-sec-title">Contact / Identity</span><span className="mn-form-sec-opt">required: name + email or phone</span></div>
        <div className="mn-form-grid">
          <Field label="First name" required error={touched && firstErr ? 'Min. 2 characters' : undefined}><Input fullWidth value={f.first} onChange={(v) => set('first', v)} placeholder="Lukas" autoFocus /></Field>
          <Field label="Last name"><Input fullWidth value={f.last} onChange={(v) => set('last', v)} placeholder="Berger" /></Field>
          <Field label="Email" required={!f.phone} error={touched && noChannel ? 'Email or phone required' : undefined}><Input fullWidth icon="mail" value={f.email} onChange={(v) => set('email', v)} placeholder="name@company.com" /></Field>
          <Field label="Phone" required={!f.email}><Input fullWidth icon="phone" value={f.phone} onChange={(v) => set('phone', v)} placeholder="+41 …" /></Field>
        </div>
      </div>
      {mode === 'full' ? (
        <React.Fragment>
          <div className="mn-form-sec">
            <div className="mn-form-sec-h"><span className="num">2</span><span className="mn-form-sec-title">Account & details</span></div>
            <div className="mn-form-grid">
              <Field label="Account" hint="Relationship — link or create new"><Input fullWidth icon="building-2" value={f.account} onChange={(v) => set('account', v)} placeholder="Alpenbau AG" /></Field>
              <Field label="Job title"><Input fullWidth value={f.jobTitle} onChange={(v) => set('jobTitle', v)} placeholder="Head of Procurement" /></Field>
              <Field label="Country / City"><Input fullWidth value={f.country} onChange={(v) => set('country', v)} placeholder="Zürich, CH" /></Field>
              <Field label="Website"><Input fullWidth icon="globe" value={f.website} onChange={(v) => set('website', v)} placeholder="company.com" /></Field>
            </div>
          </div>
          <div className="mn-form-sec">
            <div className="mn-form-sec-h"><span className="num">3</span><span className="mn-form-sec-title">Ownership & classification</span></div>
            <div className="mn-form-grid">
              <Field label="Owner" required><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
              <Field label="Source name"><Select fullWidth value={f.sourceName} onChange={(v) => set('sourceName', v)} options={SOURCE_NAMES} placeholder="Channel…" /></Field>
              <div className="mn-col-2"><Field label="Tags"><TagInput tags={f.tags} onChange={(v) => set('tags', v)} suggestions={TAG_SUGGEST} /></Field></div>
              <div className="mn-col-2"><Field label="Notes" hint="Saved as first note activity"><Textarea fullWidth value={f.notes} onChange={(v) => set('notes', v)} maxLength={500} placeholder="First note…" /></Field></div>
            </div>
          </div>
          <div className="mn-row" style={{ gap: 12, padding: '4px 0', font: 'var(--font-weight-medium) 12px/16px var(--font-sans)', color: 'var(--text-3)' }}>
            <span className="mn-chip mn-chip--bs-prospect"><Icon name="circle-dashed" size="xs" stroke="2" />Prospect</span>
            <span className="mn-chip mn-chip--as-active"><Icon name="zap" size="xs" stroke="2" />Active</span>
            <span>Defaults on create. Try email <b>lukas@alpenbau.ch</b> for duplicate flow.</span>
          </div>
        </React.Fragment>
      ) : (
        <React.Fragment>
          <div className="mn-form-grid" style={{ marginTop: 4 }}>
            <Field label="Owner" required><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
            <Field label="Source type"><Input fullWidth value="manual" disabled /></Field>
          </div>
          <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 8 }}>Defaults: Prospect · Active. Full fields via “+ Add Client”.</div>
        </React.Fragment>
      )}
    </React.Fragment>
  );

  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon="check" onClick={save} disabled={touched && !valid}>Create client</Button>
  </React.Fragment>;
  const Wrapper = mode === 'full' ? Drawer : Modal;
  const wrapProps = mode === 'full'
    ? { open: true, onClose, width: 560, eyebrow: 'Clients', title: 'Add client', subtitle: 'Full form · deep-linkable /clients/new', footer }
    : { open: true, onClose, eyebrow: 'Quick create', title: 'New client', size: 'md', footer };

  return (
    <React.Fragment>
      <Wrapper {...wrapProps}>{body}</Wrapper>
      {dup ? <DuplicateModal kind="client" dup={dup} role={role} onClose={() => setDup(null)}
                onOpenExisting={() => { setDup(null); onClose(); onOpenRecord({ kind: 'client', id: dup.record.id }); }}
                onCreateAnyway={() => { setDup(null); onToast('Client created (duplicate override flagged)'); onClose(); }} /> : null}
    </React.Fragment>
  );
}

// ---------- Create Deal -----------------------------------------------------
function CreateDealForm({ role, presetParentKind, presetParentId, onConvertLead, onClose, onToast }) {
  const [f, setF] = useStateForm({ name: '', parentKind: presetParentKind || 'client', parent: presetParentId || '', amount: '', stage: 'discovery', owner: window.MonolitRBAC.ME, close: '' });
  const [touched, setTouched] = useStateForm(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  // Opened from a Lead/Client record → relationship_status is fixed & read-only (deals-tab.md): no manual toggle.
  const locked = !!presetParentId;
  const presetLabel = locked ? (((presetParentKind === 'lead' ? window.MonolitData.leads : window.MonolitData.clients).find(r => r.id === presetParentId) || {}).name || presetParentId) : null;
  const nameErr = f.name.trim().length < 2;
  const parentOpts = (f.parentKind === 'client' ? window.MonolitData.clients : window.MonolitData.leads)
    .map(r => ({ value: r.id, label: r.name + (r.account || r.company ? ' · ' + (r.account || r.company) : '') }));
  const valid = !nameErr && f.parent;

  function save() {
    setTouched(true);
    if (!valid) return;
    onToast('Deal created · ' + f.name);
    onClose();
  }
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon="check" onClick={save} disabled={touched && !valid}>Create deal</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} eyebrow="Deals" title="New deal" size="md" footer={footer}>
      <div className="mn-form-grid">
        <div className="mn-col-2"><Field label="Deal name" required error={touched && nameErr ? 'Min. 2 characters' : undefined}><Input fullWidth value={f.name} onChange={(v) => set('name', v)} placeholder="Acme — annual subscription" autoFocus /></Field></div>
        {locked ? (
          <div className="mn-col-2"><Field label="Linked to">
            <div className="mn-row" style={{ gap: 8, padding: '8px 10px', border: '1px solid var(--border-1)', borderRadius: 'var(--radi-sm)', background: 'var(--bg-2)' }}>
              <Icon name={presetParentKind === 'lead' ? 'user' : 'building-2'} size="sm" color="text-3" />
              <span style={{ font: 'var(--font-weight-medium) 13px/16px var(--font-sans)', color: 'var(--text-1)' }}>{presetLabel}</span>
              <span className="mn-chip mn-chip--tag" style={{ marginLeft: 'auto' }}>{presetParentKind === 'lead' ? 'Lead-linked (pre-sales)' : 'Client-linked'}</span>
            </div>
          </Field></div>
        ) : (
          <React.Fragment>
            <Field label="Linked to"><SegControl value={f.parentKind} onChange={(v) => { set('parentKind', v); set('parent', ''); }} options={[{ value: 'client', label: 'Client' }, { value: 'lead', label: 'Lead (pre-sales)' }]} /></Field>
            <Field label={f.parentKind === 'client' ? 'Client' : 'Lead'} required error={touched && !f.parent ? 'Select a record' : undefined}><Select fullWidth value={f.parent} onChange={(v) => set('parent', v)} options={parentOpts} placeholder="Search…" /></Field>
          </React.Fragment>
        )}
        <Field label="Stage"><Select fullWidth value={f.stage} onChange={(v) => set('stage', v)} options={ACTIVE_STAGES.map(s => ({ value: s, label: DEAL_STAGES[s].label }))} /></Field>
        <Field label="Amount (optional)" hint="Required from Proposal onward"><Input fullWidth value={f.amount} onChange={(v) => set('amount', v)} placeholder="€ 0" /></Field>
        <Field label="Owner" required><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
        <Field label="Expected close"><Input fullWidth icon="calendar" value={f.close} onChange={(v) => set('close', v)} placeholder="dd mmm yyyy" /></Field>
      </div>
      {f.parentKind === 'lead' ? (
        <div className="mn-robanner" style={{ marginTop: 14, marginBottom: 0, alignItems: 'center' }}>
          <Icon name="info" size="sm" /><span style={{ flex: 1 }}>Pre-sales deal: Won stays blocked until the lead is converted.</span>
          {onConvertLead ? <Button variant="secondary" size="sm" icon="check-check" onClick={onConvertLead}>Convert lead</Button> : null}
        </div>
      ) : null}
    </Modal>
  );
}

// ---------- Add Activity ----------------------------------------------------
// Fields change per type — a single fixed set is not allowed (activity-comments-and-timeline.md
// §"Природа активностей": logged call/email/note vs planned task/meeting). Email is a send-from-card
// ACTION (To/Subject/Body → Send), not a log with an outcome. Task has no outcome/reason/duration and
// requires Owner + Due date. Note is just text + optional category. Outcome is MUST for Call & Meeting;
// reason_code is conditional (only Cancelled / Rescheduled / No Answer / Wrong Number).
const ACT_TYPES = [
  { value: 'call', label: 'Call', icon: 'phone' },
  { value: 'email', label: 'Email', icon: 'mail' },
  { value: 'meeting', label: 'Meeting', icon: 'calendar' },
  { value: 'task', label: 'Task', icon: 'check-square' },
  { value: 'note', label: 'Note', icon: 'sticky-note' },
];
// Outcome enums per type (doc §Outcome). Task & Note have NO outcome. Email outcome is auto (Sent).
const ACT_OUTCOMES = {
  call: [{ value: 'connected', label: 'Connected' }, { value: 'no_answer', label: 'No Answer' }, { value: 'voicemail', label: 'Voicemail' }, { value: 'wrong_number', label: 'Wrong Number' }],
  meeting: [{ value: 'held', label: 'Held' }, { value: 'cancelled', label: 'Cancelled' }, { value: 'rescheduled', label: 'Rescheduled' }],
};
// reason_code required ONLY at outcome ∈ {Cancelled, Rescheduled, No Answer, Wrong Number} (E7 / AC-ACT-002).
// Enum set is conditional on the triggering outcome; "Other" needs a free-text reason_note.
const ACT_REASONS_BY_OUTCOME = {
  cancelled: [
    { value: 'not_interested', label: 'Not interested' }, { value: 'no_budget', label: 'No budget' },
    { value: 'no_authority', label: 'No authority' }, { value: 'lost_competitor', label: 'Lost to competitor' },
    { value: 'bad_timing', label: 'Bad timing (postponed)' }, { value: 'duplicate', label: 'Duplicate or created in error' },
    { value: 'internal', label: 'Internal reason' }, { value: 'other', label: 'Other' },
  ],
  rescheduled: [
    { value: 'client_request', label: 'Client request' }, { value: 'team_conflict', label: 'Our team conflict' },
    { value: 'attendee_unavailable', label: 'Key attendee unavailable' }, { value: 'awaiting_docs', label: 'Awaiting documents or info' },
    { value: 'other', label: 'Other' },
  ],
  no_answer: [
    { value: 'no_response', label: 'No response after attempts' }, { value: 'invalid_number', label: 'Number invalid or disconnected' },
    { value: 'wrong_contact', label: 'Wrong contact' }, { value: 'gatekeeper', label: 'Gatekeeper block' },
    { value: 'other', label: 'Other' },
  ],
};
ACT_REASONS_BY_OUTCOME.wrong_number = ACT_REASONS_BY_OUTCOME.no_answer;
const REASON_TRIGGERS = ['cancelled', 'rescheduled', 'no_answer', 'wrong_number'];
const NOTE_CATEGORIES = [
  { value: '', label: 'General' }, { value: 'objection', label: 'Objection' },
  { value: 'competitor', label: 'Competitor intel' }, { value: 'risk', label: 'Risk' }, { value: 'internal', label: 'Internal' },
];
const ACT_TITLES = { call: 'Log call', email: 'Send email', meeting: 'Schedule meeting', task: 'New task', note: 'Add note' };

function AddActivityForm({ role, entityLabel, entityEmail, presetType, onClose, onToast }) {
  const [type, setType] = useStateForm(ACT_TYPES.some(t => t.value === presetType) ? presetType : 'call');
  const [f, setF] = useStateForm({
    summary: '', outcome: '', reasonCode: '', reasonNote: '', duration: '', when: '', attendees: '',
    due: '', priority: 'medium', owner: window.MonolitRBAC.ME, reminder: false, category: '',
    to: entityEmail || '', subject: '', body: '',
  });
  const [touched, setTouched] = useStateForm(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const isEmail = type === 'email', isTask = type === 'task', isNote = type === 'note';
  const isCall = type === 'call', isMeeting = type === 'meeting';
  const showOutcome = isCall || isMeeting;                            // interaction outcome
  const outcomeRequired = isCall || isMeeting;                        // MUST for call & meeting (AC-ACT-001)
  const reasonRequired = showOutcome && REASON_TRIGGERS.includes(f.outcome); // conditional (AC-ACT-002)
  const reasonNoteRequired = reasonRequired && f.reasonCode === 'other';
  const reasonOptions = reasonRequired ? (ACT_REASONS_BY_OUTCOME[f.outcome] || []) : [];

  const errs = {
    summary: !isEmail && f.summary.trim().length < 2,
    outcome: outcomeRequired && !f.outcome,
    reason: reasonRequired && !f.reasonCode,
    reasonNote: reasonNoteRequired && !f.reasonNote.trim(),
    owner: isTask && !f.owner,
    due: isTask && !f.due.trim(),
    to: isEmail && !f.to.trim(),
    subject: isEmail && !f.subject.trim(),
  };
  const invalid = Object.values(errs).some(Boolean);

  function save() {
    setTouched(true);
    if (invalid) return;
    if (isEmail) onToast('Email sent to ' + (f.to || entityLabel) + ' · logged as activity');
    else if (isTask) onToast('Task created' + (f.due ? ' · due ' + f.due : ''));
    else if (isNote) onToast('Note added');
    else onToast(ACT_TYPES.find(t => t.value === type).label + ' logged');
    onClose();
  }

  const submitLabel = isEmail ? 'Send email' : isTask ? 'Create task' : isNote ? 'Add note' : isMeeting ? 'Save meeting' : 'Log activity';
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon={isEmail ? 'send' : 'check'} onClick={save} disabled={touched && invalid}>{submitLabel}</Button>
  </React.Fragment>;

  return (
    <Modal open onClose={onClose} eyebrow={entityLabel ? 'Activity · ' + entityLabel : 'Activity'} title={ACT_TITLES[type] || 'Add activity'} size="md" footer={footer}>
      <div className="mn-seg" style={{ marginBottom: 14, flexWrap: 'wrap' }}>
        {ACT_TYPES.map(t => (
          <button key={t.value} type="button" className={'mn-seg-btn' + (type === t.value ? ' mn-seg-btn--on' : '')} onClick={() => { setType(t.value); setTouched(false); set('outcome', ''); set('reasonCode', ''); set('reasonNote', ''); }}>
            <span className="mn-row" style={{ gap: 5 }}><Icon name={t.icon} size="xs" stroke="2" />{t.label}</span>
          </button>
        ))}
      </div>

      {isEmail ? (
        /* Email = send-from-card action (To / Subject / Body → Send), not a log with an outcome. */
        <div className="mn-form-grid">
          <div className="mn-col-2"><Field label="To" required error={touched && errs.to ? 'Recipient required' : undefined}><Input fullWidth icon="mail" value={f.to} onChange={(v) => set('to', v)} placeholder="name@company.com" /></Field></div>
          <div className="mn-col-2"><Field label="Subject" required error={touched && errs.subject ? 'Subject required' : undefined}><Input fullWidth value={f.subject} onChange={(v) => set('subject', v)} placeholder="Following up on our conversation" autoFocus /></Field></div>
          <div className="mn-col-2"><Field label="Message"><Textarea fullWidth value={f.body} onChange={(v) => set('body', v)} rows={5} maxLength={5000} placeholder="Write your email…" /></Field></div>
          <div className="mn-col-2"><div className="mn-robanner" style={{ marginTop: 0, alignItems: 'center' }}><Icon name="info" size="sm" /><span style={{ flex: 1 }}>Sent from the card via transactional provider; auto-logged as an <b style={{ margin: '0 4px' }}>email</b> activity (outcome Sent). No inbox sync in MVP.</span></div></div>
        </div>
      ) : (
        <div className="mn-form-grid">
          <div className="mn-col-2"><Field label={isTask ? 'Task title' : isNote ? 'Note' : 'Summary'} required error={touched && errs.summary ? 'Required' : undefined}>
            <Textarea fullWidth value={f.summary} onChange={(v) => set('summary', v)} rows={isNote ? 4 : 2} maxLength={isTask ? 150 : 2000} placeholder={isCall ? 'What was discussed…' : isTask ? 'What needs doing…' : isNote ? 'Write a note…' : 'Agenda / details…'} autoFocus />
          </Field></div>

          {/* Note — text + optional category only (no outcome/reason/duration) */}
          {isNote ? <div className="mn-col-2"><Field label="Category" hint="Optional · for filtering & analytics"><Select fullWidth value={f.category} onChange={(v) => set('category', v)} options={NOTE_CATEGORIES} /></Field></div> : null}

          {/* Call / Meeting — outcome (required) + conditional reason + duration */}
          {showOutcome ? <Field label="Outcome" required error={touched && errs.outcome ? 'Required' : undefined}><Select fullWidth value={f.outcome} onChange={(v) => { set('outcome', v); set('reasonCode', ''); set('reasonNote', ''); }} options={ACT_OUTCOMES[type] || []} placeholder="Select outcome…" /></Field> : null}
          {reasonRequired ? <Field label="Reason code" required error={touched && errs.reason ? 'Required for this outcome' : undefined}><Select fullWidth value={f.reasonCode} onChange={(v) => set('reasonCode', v)} options={reasonOptions} placeholder="Select a reason…" /></Field> : null}
          {reasonNoteRequired ? <div className="mn-col-2"><Field label="Reason detail" required error={touched && errs.reasonNote ? 'Required for “Other”' : undefined}><Input fullWidth value={f.reasonNote} onChange={(v) => set('reasonNote', v)} placeholder="Describe the reason…" /></Field></div> : null}
          {isCall || isMeeting ? <Field label="Duration" hint="Optional · hh:mm:ss"><Input fullWidth icon="clock" value={f.duration} onChange={(v) => set('duration', v)} placeholder="hh:mm:ss" /></Field> : null}

          {/* Meeting — scheduled event: when + attendees */}
          {isMeeting ? <Field label="When"><Input fullWidth icon="calendar" value={f.when} onChange={(v) => set('when', v)} placeholder="dd mmm · hh:mm" /></Field> : null}
          {isMeeting ? <Field label="Attendees" hint="Comma-separated"><Input fullWidth icon="users" value={f.attendees} onChange={(v) => set('attendees', v)} placeholder="Names / emails" /></Field> : null}

          {/* Task — Owner + Due date required (no outcome/reason/duration) */}
          {isTask ? <Field label="Owner" required error={touched && errs.owner ? 'Required' : undefined}><OwnerPicker value={f.owner} onChange={(v) => set('owner', v)} role={role} /></Field> : null}
          {isTask ? <Field label="Due date" required error={touched && errs.due ? 'Required' : undefined}><Input fullWidth icon="calendar" value={f.due} onChange={(v) => set('due', v)} placeholder="dd mmm · hh:mm" /></Field> : null}
          {isTask ? <Field label="Priority"><Select fullWidth value={f.priority} onChange={(v) => set('priority', v)} options={[{ value: 'high', label: 'High' }, { value: 'medium', label: 'Medium' }, { value: 'low', label: 'Low' }]} /></Field> : null}
        </div>
      )}
      {isTask ? <div style={{ marginTop: 10 }}><Checkbox checked={f.reminder} onChange={(v) => set('reminder', v)} label="Set a reminder" hint="Notifies the owner before the due date" /></div> : null}
    </Modal>
  );
}

// ---------- Edit Lead Details (modal) ---------------------------------------
// Non-inline fields per sidebar-and-edit-rules.md §Edit Rules: Company / Job Title /
// Country / City / Website. All-or-nothing save (validation on Save, not on blur).
function EditLeadDetailsModal({ lead, onClose, onSave }) {
  const [f, setF] = useStateForm({ company: lead.company || '', jobTitle: lead.jobTitle || '', country: lead.country || '', city: lead.city || '', website: lead.website || '' });
  const [touched, setTouched] = useStateForm(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const jobErr = f.jobTitle.trim().length > 0 && f.jobTitle.trim().length < 2; // min 2 only if provided
  const valid = !jobErr;
  function save() { setTouched(true); if (!valid) return; onSave({ company: f.company.trim(), jobTitle: f.jobTitle.trim(), country: f.country.trim(), city: f.city.trim(), website: f.website.trim() }); }
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon="check" onClick={save} disabled={touched && !valid}>Save changes</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} eyebrow={'Lead · ' + lead.name} title="Edit details" size="md" footer={footer}>
      <div style={{ font: 'var(--font-weight-medium) 12px/16px var(--font-sans)', color: 'var(--text-3)', marginBottom: 12 }}>
        Hot fields (Status, Owner, Next step, Tags, Phone, Email) are edited inline on the card. This form covers the rest — saved all at once.
      </div>
      <div className="mn-form-grid">
        <div className="mn-col-2"><Field label="Company"><Input fullWidth icon="building-2" value={f.company} onChange={(v) => set('company', v)} placeholder="Rivermark Logistics" autoFocus /></Field></div>
        <Field label="Job title" error={touched && jobErr ? 'Min. 2 characters' : undefined}><Input fullWidth value={f.jobTitle} onChange={(v) => set('jobTitle', v)} placeholder="Head of Procurement" /></Field>
        <Field label="Website"><Input fullWidth icon="globe" value={f.website} onChange={(v) => set('website', v)} placeholder="company.com" /></Field>
        <Field label="Country"><Input fullWidth value={f.country} onChange={(v) => set('country', v)} placeholder="USA" /></Field>
        <Field label="City"><Input fullWidth value={f.city} onChange={(v) => set('city', v)} placeholder="San Francisco" /></Field>
      </div>
    </Modal>
  );
}

Object.assign(window, { QuickCreateHub, CreateLeadForm, CreateClientForm, CreateDealForm, AddActivityForm, EditLeadDetailsModal, findDuplicate, SOURCE_NAMES, TAG_SUGGEST });
