/* Conversion, duplicate, disqualify/archive blocking & unassign-reason modals.
   Specs: leads/lead-conversion.md, lead-card/create-lead.md (dup), lead-ownership (unassign). */
const { useState: useStateConv } = React;

// ---------- Duplicate Warning modal ----------------------------------------
function DuplicateModal({ kind, dup, role, onClose, onOpenExisting, onCreateAnyway }) {
  const RB = window.MonolitRBAC;
  const canOverride = RB.can(role, kind === 'lead' ? 'clients.create' : 'clients.create') && ['Admin', 'Ops Admin', 'Manager'].includes(role);
  const r = dup.record;
  const crossHidden = dup.crossTeam && (role === 'Sales Rep' || role === 'Manager');
  const blockedSalesRep = dup.crossTeam && role === 'Sales Rep';

  const footer = <div className="mn-modal-foot--split" style={{ display: 'flex', width: '100%' }}>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <div className="mn-row" style={{ gap: 8 }}>
      {!crossHidden ? <Button variant="secondary" size="md" icon="external-link" onClick={onOpenExisting}>Open existing</Button> : null}
      {canOverride && !blockedSalesRep ? <Button variant="primary" size="md" icon="copy-plus" onClick={onCreateAnyway}>Create anyway</Button> : null}
    </div>
  </div>;

  return (
    <Modal open onClose={onClose} size="md" icon="copy" iconTone="warning"
           eyebrow="Duplicate detection" title="Possible duplicate found"
           subtitle={`Exact ${dup.matchType} match · checked tenant-wide across all statuses`} footer={footer}>
      {crossHidden ? (
        <div className="mn-robanner" style={{ marginBottom: 0 }}>
          <Icon name="shield" size="sm" />A possible duplicate exists in another team. Contact your manager or admin to proceed.
        </div>
      ) : (
        <div style={{ border: '1px solid var(--border-1)', borderRadius: 'var(--radi-md)', padding: 12 }}>
          <div className="mn-row" style={{ gap: 10, marginBottom: 8 }}>
            <Avatar user={{ initials: r.name.split(' ').map(w => w[0]).join('').slice(0, 2), color: r.owner ? r.owner.color : 'slate' }} size={32} />
            <div style={{ flex: 1 }}>
              <div style={{ font: 'var(--font-weight-strong) 14px/18px var(--font-sans)' }}>{r.name}
                {r.businessStatus
                  ? <span className="mn-chip mn-chip--bs-customer" style={{ marginLeft: 8 }}>{r.businessStatus}</span>
                  : r.status ? <span style={{ marginLeft: 8 }}><StatusBadge status={r.status} /></span> : null}
                {dup.crossTeam ? <span className="mn-chip mn-chip--tag" style={{ marginLeft: 4 }}>other team</span> : null}
              </div>
              <div style={{ font: 'var(--font-weight-medium) 12px/16px var(--font-sans)', color: 'var(--text-3)' }}>{r.id} · owner {r.owner ? r.owner.name : 'unassigned'}</div>
            </div>
          </div>
          <dl className="mn-kv" style={{ margin: 0 }}>
            <dt>Email</dt><dd>{r.email}{dup.matchType !== 'phone' ? <span className="mn-chip mn-chip--dl-won" style={{ marginLeft: 6 }}>match</span> : null}</dd>
            <dt>Phone</dt><dd>{r.phone}{dup.matchType !== 'email' ? <span className="mn-chip mn-chip--dl-won" style={{ marginLeft: 6 }}>match</span> : null}</dd>
            <dt>Last activity</dt><dd>{relTime(new Date(r.lastActivity || r.updatedAt || r.createdAt))}</dd>
          </dl>
        </div>
      )}
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        No automatic merge. {canOverride ? 'Create anyway flags the record as a possible duplicate and logs an override event.' : 'Your role can’t override — open the existing record instead.'}
      </div>
    </Modal>
  );
}

// ---------- Lead → Client Conversion modal ---------------------------------
function ConversionModal({ lead, role, onClose, onConverted }) {
  const D = window.MonolitData;
  const leadDeals = D.deals.filter(d => d.leadId === lead.id && dealIsActive(d));
  const [client, setClient] = useStateConv({ first: (lead.name || '').split(' ')[0] || '', last: (lead.name || '').split(' ').slice(1).join(' '), email: lead.email, phone: lead.phone, owner: lead.owner ? lead.owner.id : '', dupChoice: 'new' });
  const [accountMode, setAccountMode] = useStateConv(lead.company ? 'create' : 'skip');
  const [accountName, setAccountName] = useStateConv(lead.company || '');
  const [makeDeal, setMakeDeal] = useStateConv(leadDeals.length === 0);
  const [dealName, setDealName] = useStateConv('Deal: ' + lead.name);
  const [dealAmount, setDealAmount] = useStateConv('');
  const set = (k, v) => setClient(s => ({ ...s, [k]: v }));
  const ownerMissing = !client.owner;
  const valid = client.first.trim().length >= 2 && (client.email || client.phone) && !ownerMissing;

  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="secondary" size="md" icon="check-check" disabled={!valid} onClick={() => onConverted(lead, client)}>Convert</Button>
  </React.Fragment>;

  return (
    <Modal open onClose={onClose} size="lg" icon="check-check" iconTone="success"
           eyebrow="Lead → Client" title={'Convert ' + lead.name}
           subtitle="Client always created · Account & Deal optional · pre-sales deals auto re-link" footer={footer}>
      {/* Section A — Client */}
      <div className="mn-form-sec">
        <div className="mn-form-sec-h"><span className="num">A</span><span className="mn-form-sec-title">Client</span><span className="mn-form-sec-opt">required</span></div>
        <div className="mn-form-grid">
          <Field label="First name" required><Input fullWidth value={client.first} onChange={(v) => set('first', v)} /></Field>
          <Field label="Last name"><Input fullWidth value={client.last} onChange={(v) => set('last', v)} /></Field>
          <Field label="Email"><Input fullWidth icon="mail" value={client.email} onChange={(v) => set('email', v)} /></Field>
          <Field label="Phone"><Input fullWidth icon="phone" value={client.phone} onChange={(v) => set('phone', v)} /></Field>
          <Field label="Owner" required error={ownerMissing ? 'Active owner required to convert' : undefined}><OwnerPicker value={client.owner} onChange={(v) => set('owner', v)} role={role} /></Field>
          <Field label="Source type"><Input fullWidth value="lead_conversion" disabled /></Field>
        </div>
      </div>

      {/* Section B — Account */}
      <div className="mn-form-sec">
        <div className="mn-form-sec-h"><span className="num">B</span><span className="mn-form-sec-title">Account</span><span className="mn-form-sec-opt">optional</span></div>
        <SegControl value={accountMode} onChange={setAccountMode} options={[{ value: 'skip', label: 'Skip' }, { value: 'existing', label: 'Select existing' }, { value: 'create', label: 'Create new' }]} />
        {accountMode !== 'skip' ? (
          <div className="mn-form-grid" style={{ marginTop: 10 }}>
            <div className="mn-col-2"><Field label="Account name"><Input fullWidth icon="building-2" value={accountName} onChange={setAccountName} placeholder="Company / organization" /></Field></div>
          </div>
        ) : <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 8 }}>Lead company maps to Account on convert. Skip to leave it off.</div>}
      </div>

      {/* Section C — Deal */}
      <div className="mn-form-sec" style={{ marginBottom: 0 }}>
        <div className="mn-form-sec-h"><span className="num">C</span><span className="mn-form-sec-title">Deal</span><span className="mn-form-sec-opt">optional</span></div>
        {leadDeals.length ? (
          <div style={{ border: '1px solid var(--border-1)', borderRadius: 'var(--radi-md)', overflow: 'hidden', marginBottom: 10 }}>
            <div style={{ padding: '8px 12px', background: 'var(--bg-2)', font: 'var(--font-weight-strong) 12px/16px var(--font-sans)' }}>
              Existing lead deals — auto re-linked to client
            </div>
            {leadDeals.map(d => (
              <div key={d.id} className="mn-row" style={{ justifyContent: 'space-between', padding: '8px 12px', borderTop: '1px solid var(--border-1)' }}>
                <span className="mn-row" style={{ gap: 8 }}><DealStageChip stage={d.stage} /><span style={{ font: 'var(--font-weight-medium) 13px/16px var(--font-sans)' }}>{d.name}</span></span>
                <span className="mn-mono" style={{ fontSize: 12, color: 'var(--text-2)' }}>{fmtMoney(d) || '—'}</span>
              </div>
            ))}
          </div>
        ) : null}
        <Checkbox checked={makeDeal} onChange={setMakeDeal} label="Create a new deal" hint="Adds a client-linked deal alongside any re-linked ones" />
        {makeDeal ? (
          <div className="mn-form-grid" style={{ marginTop: 10 }}>
            <Field label="Deal name" required><Input fullWidth value={dealName} onChange={setDealName} /></Field>
            <Field label="Amount (optional)"><Input fullWidth value={dealAmount} onChange={setDealAmount} placeholder="€ 0" /></Field>
          </div>
        ) : null}
      </div>
    </Modal>
  );
}

// ---------- Won-block modal ------------------------------------------------
// A Lead-linked Won deal is an invalid MVP state (import/migration). Won BLOCKS Disqualify / Archive —
// there is no "cancel & continue"; an Admin must resolve the Won deal first (lead-lifecycle §2.4,
// lead-conversion §4.4). Single explicit exit, no state change.
function WonBlockModal({ lead, action, wonDeals, onClose }) {
  const verb = action === 'disqualify' ? 'Disqualify' : 'Archive';
  const total = wonDeals.reduce((s, d) => s + (d.value || 0), 0);
  return (
    <Modal open onClose={onClose} size="md" icon="lock" iconTone="error"
           eyebrow={'Lifecycle · ' + verb} title={verb + ' blocked — Won deal' + (wonDeals.length > 1 ? 's' : '') + ' linked'}
           subtitle={wonDeals.length + ' Won deal' + (wonDeals.length > 1 ? 's' : '') + ' · €' + total.toLocaleString('en-GB') + ' — requires manual Admin resolution'}
           footer={<Button variant="secondary" size="md" onClick={onClose}>Close</Button>}>
      <div className="mn-robanner" style={{ marginTop: 0 }}>
        <Icon name="lock" size="sm" />A Lead-linked <b style={{ margin: '0 4px' }}>Won</b> deal can’t be cancelled by {verb.toLowerCase()}. This is an invalid MVP state (usually from import/migration) — an Admin must resolve it first (convert the lead to re-link the deal to a Client, or correct the deal).
      </div>
      <div style={{ border: '1px solid var(--border-1)', borderRadius: 'var(--radi-md)', overflow: 'hidden', marginTop: 12 }}>
        {wonDeals.map(d => (
          <div key={d.id} className="mn-row" style={{ justifyContent: 'space-between', padding: '9px 12px', borderBottom: '1px solid var(--border-1)' }}>
            <span className="mn-row" style={{ gap: 8 }}><DealStageChip stage={d.stage} /><span style={{ font: 'var(--font-weight-medium) 13px/16px var(--font-sans)' }}>{d.name}</span></span>
            <span className="mn-mono" style={{ fontSize: 12, color: 'var(--text-2)' }}>{fmtMoney(d) || '—'} · {d.owner ? d.owner.name : '—'}</span>
          </div>
        ))}
      </div>
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        No changes made. Any active (non-Won) deals stay untouched until the Won deal is resolved and you retry.
      </div>
    </Modal>
  );
}

// ---------- Disqualify / Archive blocking modal ----------------------------
function LeadLifecycleModal({ lead, action, onClose, onConfirm }) {
  const D = window.MonolitData;
  const wonDeals = (D.deals || []).filter(d => d.leadId === lead.id && d.stage === 'won');
  const activeDeals = D.deals.filter(d => d.leadId === lead.id && dealIsActive(d));
  const total = activeDeals.reduce((s, d) => s + (d.value || 0), 0);
  const verb = action === 'disqualify' ? 'Disqualify' : 'Archive';

  // Won takes precedence over the active-deals cancel flow — block outright (BR-BA-015 / §2.4).
  if (wonDeals.length) return <WonBlockModal lead={lead} action={action} wonDeals={wonDeals} onClose={onClose} />;

  if (!activeDeals.length) {
    return <ConfirmDialog open onClose={onClose} onConfirm={() => onConfirm()} icon={action === 'archive' ? 'archive' : 'x-circle'}
      title={verb + ' this lead?'} tone="primary" confirmLabel={verb}
      body={`${lead.name} will become a read-only ${action === 'archive' ? 'archived' : 'disqualified'} record. No active deals are affected.`} />;
  }
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel operation</Button>
    <Button variant="destructive" size="md" icon="ban" onClick={() => onConfirm(activeDeals)}>Cancel active deals & continue</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} size="md" icon="alert-triangle" iconTone="error"
           eyebrow={verb} title={verb + ' blocked by active deals'}
           subtitle={`${activeDeals.length} active pre-sales deal${activeDeals.length > 1 ? 's' : ''} · €${total.toLocaleString('en-GB')} affected`} footer={footer}>
      <div className="mn-robanner" style={{ marginTop: 0 }}>
        <Icon name="alert-triangle" size="sm" />{verb}ing this lead will <b style={{ margin: '0 4px' }}>cancel</b> its active pre-sales deals. This affects pipeline and forecasting.
      </div>
      <div style={{ border: '1px solid var(--border-1)', borderRadius: 'var(--radi-md)', overflow: 'hidden' }}>
        {activeDeals.map(d => (
          <div key={d.id} className="mn-row" style={{ justifyContent: 'space-between', padding: '9px 12px', borderBottom: '1px solid var(--border-1)' }}>
            <span className="mn-row" style={{ gap: 8 }}><DealStageChip stage={d.stage} /><span style={{ font: 'var(--font-weight-medium) 13px/16px var(--font-sans)' }}>{d.name}</span></span>
            <span className="mn-mono" style={{ fontSize: 12, color: 'var(--text-2)' }}>{fmtMoney(d) || '—'} · {d.owner ? d.owner.name : '—'}</span>
          </div>
        ))}
      </div>
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        Lost deals are not affected. There is no “keep deals active” option — confirm cancels them in one transaction.
      </div>
    </Modal>
  );
}

// ---------- Unassign owner (reason required) -------------------------------
// Preset reason enum per lead-ownership-and-assignment.md §10 (7 values, comment required for `other`).
const UNASSIGN_REASONS = [
  { value: 'sales_rep_requested_removal', label: 'Sales Rep requested removal' },
  { value: 'pending_reassignment', label: 'Pending reassignment' },
  { value: 'data_quality_issue', label: 'Data quality issue' },
  { value: 'compliance_hold', label: 'Compliance / legal hold' },
  { value: 'team_restructure', label: 'Team restructure' },
  { value: 'manual_review', label: 'Under manual review' },
  { value: 'other', label: 'Other' },
];
function UnassignModal({ entityName, onClose, onConfirm }) {
  const [reason, setReason] = useStateConv('');
  const [comment, setComment] = useStateConv('');
  const [touched, setTouched] = useStateConv(false);
  const commentRequired = reason === 'other';
  const valid = reason && (!commentRequired || comment.trim().length > 0);
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="destructive" size="md" icon="user-minus" disabled={touched && !valid} onClick={() => { setTouched(true); if (valid) onConfirm(reason, comment); }}>Unassign owner</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} size="sm" icon="user-minus" iconTone="error"
           eyebrow="Destructive · Admin / Ops Admin" title="Unassign owner"
           subtitle={entityName + ' will move to the unassigned pool. No undo.'} footer={footer}>
      <Field label="Reason" required error={touched && !reason ? 'Reason is required' : undefined}>
        <Select fullWidth value={reason} onChange={setReason} options={UNASSIGN_REASONS} placeholder="Select a reason…" />
      </Field>
      <div style={{ marginTop: 12 }}>
        <Field label={'Comment' + (commentRequired ? '' : ' (optional)')} required={commentRequired} error={touched && commentRequired && !comment.trim() ? 'Comment required for “Other”' : undefined}>
          <Textarea fullWidth value={comment} onChange={setComment} maxLength={500} placeholder="Add context…" />
        </Field>
      </div>
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        Logged as <span className="mn-mono">lead.owner_unassigned</span> with reason + comment.
      </div>
    </Modal>
  );
}

// ---------- Disqualify (reason required — 8 presets) -----------------------
// lead-lifecycle-and-archivation.md §1.3: reason mandatory; "Other" → free text.
const DISQUALIFY_REASONS = [
  { value: 'no_budget', label: 'No Budget' },
  { value: 'no_response', label: 'No Response' },
  { value: 'duplicate', label: 'Duplicate' },
  { value: 'competitor', label: 'Competitor' },
  { value: 'invalid_client', label: 'Invalid Client' },
  { value: 'not_interested', label: 'Not Interested' },
  { value: 'spam', label: 'Spam' },
  { value: 'other', label: 'Other' },
];
function DisqualifyModal({ lead, onClose, onConfirm }) {
  const D = window.MonolitData;
  const wonDeals = (D.deals || []).filter(d => d.leadId === lead.id && d.stage === 'won');
  // Won blocks Disqualify outright — requires manual Admin resolution (early return before hooks).
  if (wonDeals.length) return <WonBlockModal lead={lead} action="disqualify" wonDeals={wonDeals} onClose={onClose} />;
  const activeDeals = (D.deals || []).filter(d => d.leadId === lead.id && dealIsActive(d));
  const [reason, setReason] = useStateConv('');
  const [text, setText] = useStateConv('');
  const [touched, setTouched] = useStateConv(false);
  const textRequired = reason === 'other';
  const valid = reason && (!textRequired || text.trim().length > 0);
  // BR-BA-015: continuing with active (non-Won) deals cancels them atomically — make it an explicit
  // decision (button states the cancellation), not a silent side-effect.
  const cancels = activeDeals.length;
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel operation</Button>
    <Button variant="destructive" size="md" icon="x-circle" disabled={touched && !valid} onClick={() => { setTouched(true); if (valid) onConfirm(reason, text); }}>{cancels ? 'Disqualify & cancel ' + cancels + ' deal' + (cancels > 1 ? 's' : '') : 'Disqualify lead'}</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} size="sm" icon="x-circle" iconTone="error"
           eyebrow="Lifecycle · Disqualify" title={'Disqualify ' + lead.name}
           subtitle="Final negative status · read-only after. A reason is required." footer={footer}>
      {activeDeals.length ? (
        <div className="mn-robanner" style={{ marginTop: 0, marginBottom: 12 }}>
          <Icon name="alert-triangle" size="sm" />Continuing will <b style={{ margin: '0 4px' }}>cancel</b> {activeDeals.length} active pre-sales deal{activeDeals.length > 1 ? 's' : ''} atomically with the lead — this is your explicit decision (Lost deals are unaffected).
        </div>
      ) : null}
      <Field label="Reason" required error={touched && !reason ? 'Reason is required' : undefined}>
        <Select fullWidth value={reason} onChange={setReason} options={DISQUALIFY_REASONS} placeholder="Select a reason…" />
      </Field>
      {textRequired ? (
        <div style={{ marginTop: 12 }}>
          <Field label="Details" required error={touched && !text.trim() ? 'Required for “Other”' : undefined}>
            <Textarea fullWidth value={text} onChange={setText} maxLength={500} placeholder="Describe the reason…" />
          </Field>
        </div>
      ) : null}
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        Logged as <span className="mn-mono">lead.disqualified</span> with reason{textRequired ? ' + details' : ''}.
      </div>
    </Modal>
  );
}

// ---------- Assign / reassign owner ----------------------------------------
// lead-ownership-and-assignment.md: Manager (team scope) / Ops Admin / Admin (tenant).
function AssignOwnerModal({ lead, role, onClose, onConfirm }) {
  const [owner, setOwner] = useStateConv(lead.owner ? lead.owner.id : '');
  const [touched, setTouched] = useStateConv(false);
  const valid = !!owner;
  const reassign = !!lead.owner;
  const footer = <React.Fragment>
    <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
    <Button variant="primary" size="md" icon="user-check" disabled={touched && !valid} onClick={() => { setTouched(true); if (valid) onConfirm(owner); }}>{reassign ? 'Reassign' : 'Assign'} owner</Button>
  </React.Fragment>;
  return (
    <Modal open onClose={onClose} size="sm" icon="user-plus" iconTone="primary"
           eyebrow={'Ownership · ' + lead.name} title={reassign ? 'Reassign owner' : 'Assign owner'}
           subtitle="Assignment within your scope · logged to the lead audit." footer={footer}>
      <Field label="Owner" required error={touched && !valid ? 'Select an owner' : undefined}>
        <OwnerPicker value={owner} onChange={setOwner} role={role} />
      </Field>
      <div style={{ font: 'var(--font-weight-medium) 11px/15px var(--font-sans)', color: 'var(--text-3)', marginTop: 10 }}>
        Logged as <span className="mn-mono">lead.owner_assigned</span>.
      </div>
    </Modal>
  );
}

Object.assign(window, { DuplicateModal, ConversionModal, LeadLifecycleModal, UnassignModal, UNASSIGN_REASONS });
