// Reseller portal — Settings. Confirmed with the customer: "keep this
// simple for now" — no notification preferences, just:
//   1. A read-only company info block (tier / region / country / account
//      manager) — all already returned by GET /api/portal/me, no new
//      backend needed.
//   2. A password-change form (POST /api/portal/change-password) that
//      verifies the current password server-side before accepting a new
//      one (see routes/portal.ts).
//
// Reuses FieldBlock/DarkInput from reseller-login-page.jsx and the same
// loadMe/handleSwitchCompany pattern as every other reseller page (see
// reseller-quotes-page.jsx) so the Solo-staff "view as company" switcher
// keeps working consistently everywhere.

const SETTINGS_TIER_LABELS = { gold: "Gold partner", platinum: "Platinum partner", regional_reseller: "Regional Reseller" };

function ResellerSettingsPage({ onNavigate }) {
  const [state, setState] = useState({ status: "loading", user: null, company: null, contacts: null, isSoloStaff: false });
  const [companies, setCompanies] = useState([]);

  const loadMe = (onDone) => {
    fetch("/api/portal/me", { credentials: "same-origin" })
      .then(async (r) => {
        if (!r.ok) throw new Error("not signed in");
        return r.json();
      })
      .then((data) => {
        setState({ status: "ready", user: data.user, company: data.company, contacts: data.contacts || null, isSoloStaff: !!data.isSoloStaff });
        if (data.isSoloStaff) {
          fetch("/api/portal/companies", { credentials: "same-origin" })
            .then((r) => (r.ok ? r.json() : { companies: [] }))
            .then((d) => setCompanies(d.companies || []))
            .catch(() => setCompanies([]));
        }
        if (onDone) onDone();
      })
      .catch(() => onNavigate("reseller-login"));
  };

  const handleSwitchCompany = (companyId) => {
    fetch("/api/portal/switch-company", {
      method: "POST", credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ companyId }),
    })
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then(() => loadMe())
      .catch(() => { /* switch failed silently */ });
  };

  useEffect(() => { loadMe(); }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  if (state.status === "loading") {
    return <section style={{ background: "var(--pt-bg)", minHeight: "calc(100vh - 88px)" }} />;
  }

  const { user, company, contacts, isSoloStaff } = state;
  const accountManager = contacts && contacts.account_manager;
  const technicalContact = contacts && contacts.technical_contact;

  return (
    <ResellerShell
      page="portal-settings" onNavigate={onNavigate}
      userName={user.name} companyName={company.name}
      isSoloStaff={isSoloStaff} companies={companies}
      currentCompanyId={company.id} onSwitchCompany={handleSwitchCompany}
      subtitle="Reseller portal"
      title="Settings."
    >
      <p style={{
        fontFamily: "var(--font-body)", fontSize: 14,
        color: "var(--pt-fg-dim)", margin: "-16px 0 36px",
      }}>
        Manage your sign-in and see your company's account details at a glance.
      </p>

      {/* Company info — read-only */}
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.28em",
        textTransform: "uppercase", color: "var(--pt-fg-dimmer)", fontWeight: 500,
        marginBottom: 16,
      }}>Company</div>
      <div style={{
        background: "var(--pt-surface)", border: "1px solid var(--pt-border)",
        padding: "26px 28px", marginBottom: 44,
        display: "grid", gap: 20, gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
      }}>
        <SettingsField label="Company name" value={company.name} />
        <SettingsField label="Tier" value={SETTINGS_TIER_LABELS[company.tier] || "Pending tier"} />
        <SettingsField label="Region" value={company.region || "\u2014"} />
        <SettingsField label="Country" value={company.country || "\u2014"} />
        <SettingsField label="Account manager" value={(accountManager && accountManager.name) || "Not yet assigned"} />
        {accountManager && accountManager.email && <SettingsField label="Account manager email" value={accountManager.email} />}
        {accountManager && accountManager.phone && <SettingsField label="Account manager phone" value={accountManager.phone} />}
        <SettingsField label="Technical contact" value={(technicalContact && technicalContact.name) || "Not yet assigned"} />
        {technicalContact && technicalContact.email && <SettingsField label="Technical contact email" value={technicalContact.email} />}
        {technicalContact && technicalContact.phone && <SettingsField label="Technical contact phone" value={technicalContact.phone} />}
      </div>

      {/* Your account — read-only identity + password change */}
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.28em",
        textTransform: "uppercase", color: "var(--pt-fg-dimmer)", fontWeight: 500,
        marginBottom: 16,
      }}>Your account</div>
      <div style={{
        background: "var(--pt-surface)", border: "1px solid var(--pt-border)",
        padding: "26px 28px", marginBottom: 24,
        display: "grid", gap: 20, gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
      }}>
        <SettingsField label="Name" value={user.name} />
        <SettingsField label="Email" value={user.email} />
        <SettingsField label="Role" value={user.role === "company_admin" ? "Company admin" : "Member"} />
      </div>

      <ChangePasswordForm />
      <TwoFactorSettingsSection />
    </ResellerShell>
  );
}

// Local copy of two-factor-auth.jsx's palette shape, pointed at this
// page's --pt-* variables (same reasoning as reseller-login-page.jsx's
// RESELLER_2FA_PALETTE -- kept as its own const here rather than
// depending on cross-script-tag scope sharing of that other file's
// top-level const).
const RESELLER_SETTINGS_2FA_PALETTE = {
  bg: "var(--pt-bg)", fg: "var(--pt-fg)",
  fgDim: "var(--pt-fg-4)", fgFaint: "var(--pt-fg-faint2)",
  border: "var(--pt-border-3)", borderStrong: "var(--pt-border-strong)",
  surface: "var(--pt-surface)",
  accentBg: "var(--pt-accent-bg)", accentFg: "var(--pt-accent-fg)",
  accentBgDisabled: "var(--pt-accent-bg-disabled)", accentFgDisabled: "var(--pt-accent-fg-disabled)",
  errorBg: "var(--pt-error-bg)", errorBorder: "var(--pt-error-border)", errorText: "var(--pt-error-text)",
  successText: "var(--pt-success-text)",
};

function SettingsField({ label, value }) {
  return (
    <div>
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.16em",
        textTransform: "uppercase", color: "var(--pt-fg-faint)", fontWeight: 500, marginBottom: 6,
      }}>{label}</div>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 14.5, color: "var(--pt-fg-2)" }}>{value}</div>
    </div>
  );
}

function ChangePasswordForm() {
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [success, setSuccess] = useState("");

  const mismatch = newPassword && confirmPassword && newPassword !== confirmPassword;
  const canSubmit = currentPassword && newPassword.length >= 10 && newPassword === confirmPassword && !busy;

  const submit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setBusy(true); setError(""); setSuccess("");
    try {
      const res = await fetch("/api/portal/change-password", {
        method: "POST", credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ currentPassword, newPassword }),
      });
      const d = await res.json().catch(() => ({}));
      if (!res.ok) { setError(d.error || "Something went wrong."); setBusy(false); return; }
      setSuccess(d.message || "Your password has been changed.");
      setCurrentPassword(""); setNewPassword(""); setConfirmPassword("");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{
      background: "var(--pt-surface)", border: "1px solid var(--pt-border-3)",
      padding: "28px 30px", maxWidth: 480,
    }}>
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.28em",
        textTransform: "uppercase", color: "var(--pt-fg-dim)", fontWeight: 500, marginBottom: 20,
      }}>Change password</div>

      {error && (
        <div style={{
          background: "var(--pt-error-bg)", border: "1px solid var(--pt-error-border)",
          color: "var(--pt-error-text)", padding: "12px 14px", marginBottom: 18,
          fontFamily: "var(--font-body)", fontSize: 13, lineHeight: 1.5,
        }}>{error}</div>
      )}
      {success && (
        <div style={{
          fontFamily: "var(--font-body)", fontSize: 13, color: "var(--pt-success-text)", marginBottom: 18,
        }}>{success}</div>
      )}

      <form onSubmit={submit}>
        <FieldBlock label="Current password">
          <DarkInput
            type="password" autoComplete="current-password" required
            data-testid="settings-current-password"
            value={currentPassword} onChange={(e) => setCurrentPassword(e.target.value)}
            placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
          />
        </FieldBlock>
        <FieldBlock label="New password" hint="At least 10 characters.">
          <DarkInput
            type="password" autoComplete="new-password" required
            data-testid="settings-new-password"
            value={newPassword} onChange={(e) => setNewPassword(e.target.value)}
            placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
          />
        </FieldBlock>
        <FieldBlock label="Confirm new password">
          <DarkInput
            type="password" autoComplete="new-password" required
            data-testid="settings-confirm-password"
            value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)}
            placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
          />
        </FieldBlock>
        {mismatch && (
          <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "var(--pt-error-text)", margin: "-10px 0 22px" }}>
            Passwords don't match.
          </div>
        )}
        <button
          type="submit" disabled={!canSubmit} data-testid="settings-change-password-submit"
          style={{
            background: canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)",
            color: canSubmit ? "var(--pt-accent-fg)" : "var(--pt-accent-fg-disabled)",
            border: `1px solid ${canSubmit ? "var(--pt-accent-bg)" : "var(--pt-accent-bg-disabled)"}`,
            padding: "14px 26px", cursor: canSubmit ? "pointer" : "not-allowed",
            fontFamily: "var(--font-body)", fontSize: 12.5, fontWeight: 500,
            letterSpacing: "0.16em", textTransform: "uppercase",
          }}
        >{busy ? "Saving\u2026" : "Change password"}</button>
      </form>
    </div>
  );
}

// Self-service 2FA panel -- reset only, no disable (2FA is MANDATORY for
// every reseller/customer, see migrations/0060_two_factor_auth.sql's
// header). In the ordinary case a reseller reaches this page already
// enrolled (they were forced through it at their very next login after
// this shipped -- see reseller-login-page.jsx's "enroll" branch), so
// this mostly just shows status + a "reset" option for a lost device.
// The not-enrolled state is a defensive fallback (shouldn't normally be
// reachable) rather than the primary path.
function TwoFactorSettingsSection() {
  // loading → ready → enrolling → done (shows recovery codes once)
  const [state, setState] = useState({ phase: "loading", enrolled: false, remainingRecoveryCodes: 0 });
  const [pendingToken, setPendingToken] = useState("");
  const [otpauthUri, setOtpauthUri] = useState("");
  const [recoveryCodes, setRecoveryCodes] = useState(null);
  const [error, setError] = useState("");

  const loadStatus = () => {
    fetch("/api/portal/2fa/status", { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : { enrolled: false, remainingRecoveryCodes: 0 }))
      .then((d) => setState({ phase: "ready", enrolled: !!d.enrolled, remainingRecoveryCodes: d.remainingRecoveryCodes || 0 }))
      .catch(() => setState({ phase: "ready", enrolled: false, remainingRecoveryCodes: 0 }));
  };

  useEffect(() => { loadStatus(); }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const startEnroll = async () => {
    setError("");
    try {
      const res = await fetch("/api/portal/2fa/enroll", { method: "POST", credentials: "same-origin" });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) { setError(data.error || "Something went wrong. Please try again."); return; }
      setPendingToken(data.pendingToken);
      setOtpauthUri(data.otpauthUri);
      setState((s) => ({ ...s, phase: "enrolling" }));
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
    }
  };

  if (state.phase === "loading") return null;

  if (state.phase === "enrolling") {
    return (
      <div style={{ marginTop: 32, maxWidth: 480 }}>
        <TwoFactorEnrollCard
          confirmUrl="/api/portal/2fa/enroll/confirm"
          pendingToken={pendingToken}
          otpauthUri={otpauthUri}
          intro={state.enrolled
            ? "Scan this new QR code with your authenticator app to replace your old device, then enter the 6-digit code it shows."
            : "Scan this QR code with an authenticator app (Google Authenticator, Authy, 1Password, etc.), then enter the 6-digit code it shows."}
          onSuccess={(codes) => { setRecoveryCodes(codes); setState((s) => ({ ...s, phase: "done" })); }}
          palette={RESELLER_SETTINGS_2FA_PALETTE}
        />
      </div>
    );
  }

  if (state.phase === "done") {
    return (
      <div style={{ marginTop: 32, maxWidth: 480 }}>
        <RecoveryCodesCard
          codes={recoveryCodes}
          onContinue={() => { setRecoveryCodes(null); loadStatus(); }}
          palette={RESELLER_SETTINGS_2FA_PALETTE}
        />
      </div>
    );
  }

  return (
    <div style={{
      background: "var(--pt-surface)", border: "1px solid var(--pt-border-3)",
      padding: "28px 30px", marginTop: 32, maxWidth: 480,
    }}>
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, letterSpacing: "0.28em",
        textTransform: "uppercase", color: "var(--pt-fg-dim)", fontWeight: 500, marginBottom: 20,
      }}>Two-factor authentication</div>

      {error && (
        <div style={{
          background: "var(--pt-error-bg)", border: "1px solid var(--pt-error-border)",
          color: "var(--pt-error-text)", padding: "12px 14px", marginBottom: 18,
          fontFamily: "var(--font-body)", fontSize: 13, lineHeight: 1.5,
        }}>{error}</div>
      )}

      {state.enrolled ? (
        <>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.6, color: "var(--pt-fg-4)", margin: "0 0 8px" }}>
            Two-factor authentication is <strong style={{ color: "var(--pt-success-text)" }}>enabled</strong> on your account. It's required on every sign-in and can't be turned off.
          </p>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.6, color: "var(--pt-fg-4)", margin: "0 0 20px" }}>
            {state.remainingRecoveryCodes} unused recovery code{state.remainingRecoveryCodes === 1 ? "" : "s"} remaining.
          </p>
          <button
            type="button" onClick={startEnroll}
            style={{
              background: "none", border: "1px solid var(--pt-border-strong)", color: "var(--pt-fg-3)",
              padding: "12px 22px", cursor: "pointer",
              fontFamily: "var(--font-body)", fontSize: 12, fontWeight: 500,
              letterSpacing: "0.14em", textTransform: "uppercase",
            }}>Reset (lost device) →</button>
        </>
      ) : (
        <>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.6, color: "var(--pt-fg-4)", margin: "0 0 20px" }}>
            Two-factor authentication is required on your account but hasn't been set up yet.
          </p>
          <button
            type="button" onClick={startEnroll}
            style={{
              background: "var(--pt-accent-bg)", color: "var(--pt-accent-fg)", border: "1px solid var(--pt-accent-bg)",
              padding: "14px 26px", cursor: "pointer",
              fontFamily: "var(--font-body)", fontSize: 12.5, fontWeight: 500,
              letterSpacing: "0.16em", textTransform: "uppercase",
            }}>Set up now →</button>
        </>
      )}
    </div>
  );
}

Object.assign(window, { ResellerSettingsPage });
