// =================================================================
// pw-verification.jsx — Publisher Admin · verification and its reminder
//
//   PRD §7. An unverified publisher waits 90 days for a payout instead
//   of 60, and may be suspended. They have to be told, repeatedly, and
//   we have to be able to show that they were.
//
//   Two rules this file must never break:
//     * it never hides what a publisher has earned — the modal states
//       the held amount rather than obscuring it;
//     * it never blocks the integration or ad serving. Their readers
//       are not party to this.
//
//   The escalation stage is decided server-side (get_verification_reminder).
//   How hard to press a publisher is a policy decision; deciding it here
//   would drift per surface and could not be changed without a deploy.
// =================================================================

// D13: earnings are held, not forfeited. Saying so is both the defensible position and the more
// effective one — a publisher told their money is waiting has a reason to verify; one told they may
// lose everything has a reason to leave.
const VERIFY_ACK_TERMS = [
  "Your payouts are held for 90 days instead of 60.",
  "An unverified account may be suspended or removed at any time, without notice.",
];
const VERIFY_ACK_REASSURANCE =
  "Anything you have already earned is held, not lost — it is released when you verify.";

const VerificationReminder = ({ reminder, currency, onVerify, onAcknowledged, notify }) => {
  // Week 1 is a banner and dismissible for the session only: nothing is recorded, because there is
  // nothing yet to acknowledge. From week 2 the dismissal is an acknowledgement and is stored.
  const [dismissed, setDismissed] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const stage = reminder?.stage || "none";
  if (stage === "none" || dismissed) return null;

  const money = (n) => fmt.currency(Number(n || 0), currency || "USD");
  const held = Number(reminder?.held_amount || 0);

  const acknowledge = async () => {
    setSaving(true);
    try {
      await window.__api.write("ackVerification", null, { body: { stage } });
      setDismissed(true);
      onAcknowledged && onAcknowledged();
    } catch (e) {
      // A failed acknowledgement must not trap the publisher behind the modal. Let them past and
      // say so — the reminder returns on the next visit anyway, which is the intended behaviour.
      setDismissed(true);
      notify && notify(e.message || "Could not record that, but you can carry on.", "warn");
    } finally {
      setSaving(false);
    }
  };

  if (stage === "banner") {
    return (
      <div className="pw-card" style={{ borderLeft: "3px solid var(--warn)", padding: "12px 16px", marginBottom: 16,
        display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
        <div style={{ flex: 1, minWidth: 260, fontSize: 13, color: "var(--ink-2)" }}>
          <strong>Verify your account.</strong> It is free, takes a few minutes, and shortens how long
          your payouts are held from 90 days to 60.
        </div>
        <Btn onClick={onVerify}>Verify now</Btn>
        <Btn variant="ghost" onClick={() => setDismissed(true)}>Later</Btn>
      </div>
    );
  }

  return (
    <div className="pw-modal-backdrop" style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,.45)",
      display: "flex", alignItems: "center", justifyContent: "center", zIndex: 60, padding: 20 }}>
      <div className="pw-card" style={{ maxWidth: 520, width: "100%", padding: 24 }}>
        <h3 style={{ margin: "0 0 12px", fontSize: 17 }}>Verify your account</h3>
        <div style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.7 }}>
          <p style={{ margin: "0 0 10px" }}>Until you do:</p>
          <ul style={{ margin: "0 0 12px 18px", padding: 0 }}>
            {VERIFY_ACK_TERMS.map((t, i) => <li key={i} style={{ marginBottom: 4 }}>{t}</li>)}
          </ul>
          {/* Never hide what they have earned. Showing the number, and what verifying would do to
              its release date, is the whole argument for verifying. */}
          {held > 0 ? (
            <p style={{ margin: "0 0 12px", padding: "10px 12px", background: "var(--bg-2)", borderRadius: 8 }}>
              <strong>{money(held)}</strong> of your earnings is currently held.
              {reminder?.would_release_on
                ? <> Verify today and it releases on <strong>{reminder.would_release_on}</strong>.</>
                : null}
            </p>
          ) : null}
          <p style={{ margin: "0 0 16px" }}><strong>{VERIFY_ACK_REASSURANCE}</strong></p>
        </div>
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", flexWrap: "wrap" }}>
          <Btn variant="ghost" onClick={acknowledge} disabled={saving}>
            {saving ? "Saving…" : "I understand, continue"}
          </Btn>
          <Btn onClick={onVerify}>Verify now</Btn>
        </div>
      </div>
    </div>
  );
};

const VERIFY_FIELDS = [
  { group: "business_registration", label: "Business registration", fields: [
    { key: "legal_name", label: "Registered legal name" },
    { key: "registration_number", label: "Registration number" },
    { key: "country", label: "Country of registration", placeholder: "IN" },
  ] },
  { group: "tax_identity", label: "Tax identity", fields: [
    { key: "tax_id", label: "Tax identifier" },
    { key: "country", label: "Tax country", placeholder: "IN" },
  ] },
  { group: "bank_account", label: "Bank account", fields: [
    { key: "account_holder", label: "Account holder" },
    { key: "account_number", label: "Account number" },
    { key: "bank_name", label: "Bank name" },
    { key: "country", label: "Bank country", placeholder: "IN" },
  ] },
];

const STATUS_TONE = { verified: "good", pending: "info", rejected: "bad", unverified: "warn" };
const STATUS_COPY = {
  verified: "Verified. Your payouts are held 60 days, or 30 on a support plan.",
  pending: "Submitted and under review. Nothing more is needed from you.",
  rejected: "We could not verify this. Correct the details below and resubmit.",
  unverified: "Not verified yet. Payouts are held 90 days until you are.",
};

const VerificationCard = ({ verification, onSaved, notify }) => {
  const [form, setForm] = React.useState({});
  const [saving, setSaving] = React.useState(false);
  const status = verification?.status || "unverified";
  // Only unverified and rejected may submit — a submission under review or already approved is not
  // something a publisher's own request should disturb. The API enforces this; the UI agrees with it
  // rather than offering a button that would be refused.
  const canSubmit = status === "unverified" || status === "rejected";

  const set = (group, key, value) =>
    setForm((f) => ({ ...f, [group]: { ...(f[group] || {}), [key]: value } }));

  const submit = async () => {
    setSaving(true);
    try {
      await window.__api.write("submitVerification", null, {
        body: {
          business_registration: form.business_registration || {},
          tax_identity: form.tax_identity || {},
          bank_account: form.bank_account || {},
        },
      });
      setForm({});
      notify("Submitted for review.");
      onSaved();
    } catch (e) {
      notify(e.message || "Could not submit verification.", "bad");
    } finally {
      setSaving(false);
    }
  };

  return (
    <Card title="Account verification"
      subtitle="Free, and it halves how long your payouts are held. It cannot be bought — a support plan shortens the hold further, but only once you are verified.">
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
          <Pill tone={STATUS_TONE[status] || "neutral"}>{status}</Pill>
          <span style={{ fontSize: 13, color: "var(--ink-2)" }}>{STATUS_COPY[status]}</span>
        </div>

        {status === "rejected" && verification?.rejection_reason ? (
          <div style={{ fontSize: 13, color: "var(--bad)" }}>Reason: {verification.rejection_reason}</div>
        ) : null}

        {/* Evidence is stored and never echoed back, exactly as payout details are — the publisher
            sees which pieces are on file, never the values. */}
        <div style={{ display: "flex", gap: 14, flexWrap: "wrap", fontSize: 12, color: "var(--muted)" }}>
          <span>Business registration: {verification?.business_registration_set ? "on file" : "—"}</span>
          <span>Tax identity: {verification?.tax_identity_set ? "on file" : "—"}</span>
          <span>Bank account: {verification?.bank_account_set ? "on file" : "—"}</span>
        </div>

        {canSubmit ? (
          <>
            {VERIFY_FIELDS.map((g) => (
              <div key={g.group}>
                <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 8 }}>{g.label}</div>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
                  {g.fields.map((f) => (
                    <div key={f.key}>
                      <label className="pw-lbl">{f.label}</label>
                      <Input value={(form[g.group] || {})[f.key] || ""} placeholder={f.placeholder || ""}
                        onChange={(e) => set(g.group, f.key, e.target.value)}/>
                    </div>
                  ))}
                </div>
              </div>
            ))}
            <div style={{ display: "flex", justifyContent: "flex-end" }}>
              <Btn onClick={submit} disabled={saving}>{saving ? "Submitting…" : "Submit for review"}</Btn>
            </div>
          </>
        ) : null}
      </div>
    </Card>
  );
};
