import { FileHelper } from '@start9labs/start-sdk'
import { Volume } from '@start9labs/start-sdk/package/lib/util/Volume'
import { z } from 'zod'

const mainVolume = new Volume('main')

export const configFile = FileHelper.json(
  {
    base: mainVolume,
    subpath: 'config/startos-config.json',
  },
  z.object({
    gemini_api_key: z.string().default(''),
    anthropic_api_key: z.string().default(''),
    openai_api_key: z.string().default(''),
    openai_compatible_base_url: z.string().default(''),
    openai_compatible_api_key: z.string().default(''),
    ollama_base_url: z.string().default(''),
    whisper_base_url: z.string().default(''),
    whisper_api_key: z.string().default(''),
    // NOTE: relay_base_url was removed in 0.2.34. The relay endpoint
    // is hardcoded in server/relay-default.js and updated via Recap
    // version releases — never exposed to end users.
    recap_license_key: z.string().default(''),
    recap_admin_username: z.string().default(''),
    recap_admin_password_hash: z.string().default(''),
    recap_admin_password_salt: z.string().default(''),
    recap_admin_session_secret: z.string().default(''),
    // PodcastIndex credentials — used to resolve Spotify share URLs to
    // their underlying RSS audio enclosure. Free tier signup at
    // api.podcastindex.org. Apple Podcasts URLs resolve without auth.
    podcastindex_api_key: z.string().default(''),
    podcastindex_api_secret: z.string().default(''),
    // ── Multi-tenant cloud-mode fields (added 0.2.77) ──
    // recap_mode: "single" → existing self-hosted, one operator, no auth
    //             "multi"  → cloud mode with email + magic-link auth,
    //                        per-user library, BTCPay subscriptions
    // The .s9pk defaults to single. Operators flip to multi via the
    // "Enable multi-tenant mode" StartOS action.
    recap_mode: z.enum(['single', 'multi']).default('single'),
    // Public URL used in magic-link sign-in emails. Must be the
    // ClearNet URL pointing at the Recap UI (typically a domain
    // routed through Start Tunnel). Without this set, magic-link
    // emails won't have a working sign-in link.
    recap_public_url: z.string().default(''),
    // Shared "operator key" for the core-decoupling cloud path. The secret
    // that authenticates THIS Recap server to the Recap Relay so it can
    // vouch for its signed-in users by account-id (X-Recap-User-Id) instead
    // of attaching a per-user Keysat license. Must EXACTLY match the relay's
    // own relay_cloud_operator_key. Empty = the cloud user-id path is
    // disabled and paid users fall back to the operator's relay pool.
    // Set via the "Set Relay Operator Key" StartOS action. Server-side
    // only — never sent to the browser. Picked up live by the config poll
    // (no restart needed), same as the provider API keys.
    recap_relay_operator_key: z.string().default(''),
    // Per-tenant default credit allowance — only used when running in
    // multi mode on a self-hosted operator's StartOS server. New
    // tenants (family members who sign up on the operator's domain)
    // start with this many credits. The operator's relay-credit pool
    // is debited as their tenants summarize. Doesn't apply to the
    // canonical cloud deployment because cloud users have their own
    // keysat licenses + relay-side credit pools.
    tenant_default_credits: z.number().int().nonnegative().default(5),
    // How often a tenant's "replenishable" credit bucket is refilled
    // to tenant_default_credits.
    //   "off"     — no refill; the signup-grant is one-time
    //   "daily"   — anniversary-aligned 24h
    //   "weekly"  — anniversary-aligned 7d
    //   "monthly" — anniversary-aligned calendar month
    // Anniversary-aligned = anchored to each tenant's last_replenish_at
    // (set when they signed up or when the operator first turned the
    // period on). Purchased credits + admin grants are persisted in
    // tenant_credits.purchased_balance and NEVER affected by refills —
    // only the replenish_balance bucket gets reset to the configured N.
    tenant_credit_replenish_period: z
      .enum(["off", "daily", "weekly", "monthly"])
      .default("off"),
    // Anonymous-trial knobs (multi-mode only). Visitors who land on
    // recapapp.xyz without an account get N free summaries gated by a
    // browser cookie before being prompted to sign up. Set
    // trial_credits_per_visitor=0 to disable trials (return to an
    // auth-wall landing). trials_per_ip_per_day caps how many distinct
    // trial cookies one IP can mint in 24h — anti-script-abuse floor.
    trial_credits_per_visitor: z.number().int().nonnegative().default(1),
    // Lifetime cap on the number of distinct trial cookies one IP can
    // mint. Was previously rolling-24h; switched to lifetime so a user
    // who clears cookies can't replay the trial every day. The legacy
    // field name `trials_per_ip_per_day` is preserved below as a
    // read-only alias so installs that already have it set don't lose
    // their value during the rename — anon-trial.js prefers
    // _lifetime if set, falls back to _per_day if not.
    trials_per_ip_lifetime: z.number().int().positive().default(5),
    // Legacy alias — read for backward compatibility with v0.2.77–0.2.83
    // installs that wrote the per-day variant. Will be removed once
    // all known installs have re-saved their config under the new key.
    trials_per_ip_per_day: z.number().int().positive().default(5),
    // ── SMTP — synced from StartOS System SMTP via the SDK ──
    // main.ts subscribes to effects.getSystemSmtp() and writes these
    // fields here whenever the operator changes the system SMTP. The
    // server reads them through the same file-poll as everything else
    // and (re)builds its nodemailer transport. NEVER edit these
    // fields directly — they get overwritten on the next sync.
    smtp_host: z.string().default(''),
    smtp_port: z.number().int().default(0),
    smtp_security: z.enum(['starttls', 'tls']).default('tls'),
    smtp_username: z.string().default(''),
    smtp_password: z.string().default(''),
    smtp_from: z.string().default(''),
  }),
)
