import { type PlannerNoChange } from '../../../core/src/index';
import { type BillingPlanId } from '../plans/types';
export type BillingComponentInterval = 'month' | 'year';
export type BillingComponentCurrencyCode = string;
export type BillingComponentId = string;
export type BillingComponentSiteId = string;
export type BillingComponentSiteDomainId = string;
export type BillingComponentKind = 'plan_base' | 'custom_site_price' | 'extra_site' | 'managed_domain_overage';
export type BillingComponentPersistenceStatus = 'pending_acceptance' | 'accepted' | 'sync_failed' | 'registrar_failed' | 'registrar_succeeded_persist_failed' | 'active' | 'ending' | 'ended' | 'failed';
export type EndableBillingComponentStatus = Extract<BillingComponentPersistenceStatus, 'active' | 'ending'>;
export type EndableBillingComponentKind = Extract<BillingComponentKind, 'extra_site' | 'managed_domain_overage'>;
export type BillingComponentProposalPlan = Readonly<{
    idempotencyKey: string;
    pendingSourceKey: string;
    userId: string;
    siteId: string | null;
    kind: 'extra_site' | 'managed_domain_overage';
    amountCents: number;
    currency: string;
    interval: BillingComponentInterval;
    sourceEntity: BillingComponentSourceEntityPlan;
    snapshotHash: string;
    pricingSnapshot: unknown;
}>;
export type BillingComponentSourceEntityPlan = Readonly<{
    type: 'site';
    id: string;
}> | Readonly<{
    type: 'site_domain';
    id: string | null;
}>;
export type BillingComponentOrigin = 'computed' | 'planned' | 'persisted';
export type BillingComponentPlanSource = Readonly<{
    kind: 'plan';
    planId: string;
}>;
export type BillingComponentSiteSource = Readonly<{
    kind: 'site';
    siteId: BillingComponentSiteId;
}>;
export type BillingComponentSiteDomainSource = Readonly<{
    kind: 'site_domain';
    siteId: BillingComponentSiteId;
    siteDomainId: BillingComponentSiteDomainId;
}>;
export type BillingComponentSource = BillingComponentPlanSource | BillingComponentSiteSource | BillingComponentSiteDomainSource;
export type BillingComponentSourceForKind<TKind extends BillingComponentKind> = TKind extends 'plan_base' ? BillingComponentPlanSource : TKind extends 'custom_site_price' | 'extra_site' ? BillingComponentSiteSource : TKind extends 'managed_domain_overage' ? BillingComponentSiteDomainSource : never;
export type BillingComponentBase<TKind extends BillingComponentKind, TOrigin extends BillingComponentOrigin> = Readonly<{
    origin: TOrigin;
    kind: TKind;
    source: BillingComponentSourceForKind<TKind>;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>;
export type MacadamiaExtraSiteBillingComponentProposalPlan = BillingComponentProposalPlan & Readonly<{
    kind: 'extra_site';
    siteId: string;
    sourceEntity: Readonly<{
        type: 'site';
        id: string;
    }>;
    pricingSnapshot: MacadamiaExtraSitePricingSnapshot;
}>;
export type ManagedDomainOverageBillingComponentProposalPlan<TPricingSnapshot = unknown> = BillingComponentProposalPlan & Readonly<{
    kind: 'managed_domain_overage';
    siteId: string;
    sourceEntity: Readonly<{
        type: 'site_domain';
        id: string | null;
    }>;
    pricingSnapshot: TPricingSnapshot;
}>;
export type ComputedBillingComponent = (BillingComponentBase<'plan_base', 'computed'> & Readonly<{
    label: string;
}>) | (BillingComponentBase<'custom_site_price', 'computed'> & Readonly<{
    label: string;
}>);
export type PlannedPersistedBillingComponent = (BillingComponentBase<'extra_site', 'planned'> & Readonly<{
    label: string;
}>) | (BillingComponentBase<'managed_domain_overage', 'planned'> & Readonly<{
    label: string;
}>);
export type PersistedBillingComponent = BillingComponentBase<'extra_site', 'persisted'> | BillingComponentBase<'managed_domain_overage', 'persisted'>;
export type BillingComponent = ComputedBillingComponent | PlannedPersistedBillingComponent | PersistedBillingComponent;
export type BillingModelDecision = Readonly<{
    kind: 'macadamia_user_plan';
    reason: 'no_custom_site_prices';
}> | Readonly<{
    kind: 'custom_site_billing';
    reason: 'active_custom_site_prices';
}>;
export type BillingComponentResolution = Readonly<{
    model: BillingModelDecision;
    components: readonly BillingComponent[];
    basePlanCents: number;
    customSitePricesCents: number;
    extraSiteCents: number;
    recurringAddOnsCents: number;
    totalCents: number;
}>;
export type BillingSiteCostBreakdown = Readonly<{
    siteId: BillingComponentSiteId;
    siteName: string;
    costCents: number;
    billingStartsAt: string | null;
}>;
export type BillingBasePricePlan = Readonly<{
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    isCustomPrice: boolean;
    source: 'override' | 'base';
}>;
export type BillingTotalPricePlan = BillingBasePricePlan & Readonly<{
    billingModel: BillingModelDecision;
    basePlanCents: number;
    customSitePricesCents: number;
    extraSiteCents: number;
    recurringAddOnsCents: number;
    totalCents: number;
    siteBreakdown: readonly BillingSiteCostBreakdown[];
    componentBreakdown: readonly BillingComponent[];
}>;
export type BillingComponentCompatibilityMismatch = Readonly<{
    tag: 'component_interval_currency_mismatch';
    componentInterval: BillingComponentInterval;
    requestedInterval: BillingComponentInterval;
    componentCurrency: BillingComponentCurrencyCode;
    requestedCurrency: BillingComponentCurrencyCode;
}>;
export type BillingTotalPricePlanError = Readonly<{
    tag: 'base_price_required';
}> | Readonly<{
    tag: 'hybrid_billing_forbidden';
    customSiteIds: readonly string[];
    extraSiteIds: readonly string[];
}>;
export type BillingTotalPricePlanResult = Readonly<{
    success: true;
    data: BillingTotalPricePlan;
}> | Readonly<{
    success: false;
    error: BillingTotalPricePlanError;
}>;
export type BillingComponentSummaryBase<TKind extends BillingComponentKind> = Readonly<{
    kind: TKind;
    label: string;
    amountCents: number;
    formatted: string;
    interval: BillingComponentInterval;
}>;
export type BillingComponentSummaryBasePlanComponent = BillingComponentSummaryBase<'plan_base'> & Readonly<{
    source: BillingComponentPlanSource;
}>;
export type BillingComponentSummarySiteComponent = BillingComponentSummaryBase<'custom_site_price'> & Readonly<{
    source: BillingComponentSiteSource;
}>;
export type BillingComponentSummaryAddOnComponent = (BillingComponentSummaryBase<'extra_site'> & Readonly<{
    source: BillingComponentSiteSource;
}>) | (BillingComponentSummaryBase<'managed_domain_overage'> & Readonly<{
    source: BillingComponentSiteDomainSource;
}>);
export type BillingComponentSummaryComponent = BillingComponentSummaryBasePlanComponent | BillingComponentSummarySiteComponent | BillingComponentSummaryAddOnComponent;
export type BillingComponentSummary = Readonly<{
    basePlan: BillingComponentSummaryBasePlanComponent | null;
    sites: BillingComponentSummarySiteComponent[];
    addOns: BillingComponentSummaryAddOnComponent[];
    total: Readonly<{
        amountCents: number;
        formatted: string;
    }>;
    isCustomPrice: boolean;
}>;
export type BillingComponentSummaryError = Readonly<{
    tag: 'missing_component_label';
    componentKind: PersistedBillingComponent['kind'];
    sourceId: string;
}>;
export type BillingComponentSummaryResult = Readonly<{
    success: true;
    data: BillingComponentSummary;
}> | Readonly<{
    success: false;
    error: BillingComponentSummaryError;
}>;
export type BillingComponentSummaryFormatter = (amountCents: number, currency: BillingComponentCurrencyCode) => string;
export type BillingComponentSummaryLabelRequirements = Readonly<{
    extraSiteIds: readonly BillingComponentSiteId[];
    siteDomainIds: readonly BillingComponentSiteDomainId[];
}>;
export type BillableSiteState = Readonly<{
    tag: 'draft';
}> | Readonly<{
    tag: 'billable_live';
    launchedAt: string;
}> | Readonly<{
    tag: 'not_billable';
    reason: 'archived' | 'deleted';
}>;
export type BillableMacadamiaSite = Readonly<{
    siteId: BillingComponentSiteId;
    siteName: string;
    state: BillableSiteState;
    grandfathered?: boolean;
}>;
export type MacadamiaExtraSitePricingSnapshot = Readonly<{
    formulaVersion: 'macadamia-extra-site-v1';
    planId: BillingPlanId;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>;
export type ExtraSitePricingPolicy = Readonly<{
    includedSiteCount: number;
    currency: BillingComponentCurrencyCode;
    extraSite: Readonly<{
        tag: 'not_supported';
    }> | Readonly<{
        tag: 'priced';
        monthlyAmountCents: number;
    }>;
}>;
export type ConfiguredExtraSitePricingPolicy = ExtraSitePricingPolicy & Readonly<{
    extraSite: Readonly<{
        tag: 'priced';
        monthlyAmountCents: number;
    }>;
}>;
export type MacadamiaSiteAllowancePricingInput = Readonly<{
    includedLiveSiteCount: number;
    extraSite: Readonly<{
        tag: 'not_supported';
    }> | Readonly<{
        tag: 'priced';
        monthlyPricePence: number;
    }>;
}>;
export type ActiveExtraSiteComponentForReconciliation = Readonly<{
    componentId: BillingComponentId;
    siteId: BillingComponentSiteId;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>;
export type MacadamiaExtraSiteReconciliationAction = Readonly<{
    tag: 'requires_acceptance';
    site: BillableMacadamiaSite;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}> | Readonly<{
    tag: 'create_missing';
    site: BillableMacadamiaSite;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}> | Readonly<{
    tag: 'end_at_period_end';
    component: ActiveExtraSiteComponentForReconciliation;
    reason: 'site_no_longer_billable' | 'site_within_allowance' | 'site_grandfathered';
}> | Readonly<{
    tag: 'invalid_state';
    reason: 'duplicate_active_component';
    siteId?: BillingComponentSiteId;
}> | Readonly<{
    tag: 'requires_plan_upgrade';
    site: BillableMacadamiaSite;
    minimumPlanId: 'solo';
}>;
export type MacadamiaExtraSiteReconciliationPlan = PlannerNoChange | Readonly<{
    tag: 'changes_required';
    actions: readonly MacadamiaExtraSiteReconciliationAction[];
}>;
export type MacadamiaExtraSiteLaunchDecision = Readonly<{
    tag: 'allowed';
    reason: 'within_included_allowance';
}> | Readonly<{
    tag: 'allowed';
    reason: 'accepted_extra_site_component';
    componentId?: BillingComponentId;
}> | Readonly<{
    tag: 'requires_plan_upgrade';
    currentPlanId: BillingPlanId;
    minimumPlanId: 'solo';
}> | Readonly<{
    tag: 'requires_acceptance';
    currentPlanId: BillingPlanId;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>;
export type MacadamiaSiteCreationBillingNotice = Readonly<{
    tag: 'none';
    reason: 'within_included_allowance' | 'accepted_extra_site_component';
}> | Readonly<{
    tag: 'unknown';
    reason: 'billing_lookup_failed';
}> | Readonly<{
    tag: 'upgrade_required_on_launch';
    currentPlanId: BillingPlanId;
    minimumPlanId: 'solo';
}> | Readonly<{
    tag: 'extra_site_charge_on_launch';
    currentPlanId: BillingPlanId;
    amountCents: number;
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>;
export type MacadamiaExtraSiteProposalDecisionPlan = Extract<MacadamiaExtraSiteLaunchDecision, {
    tag: 'requires_acceptance';
}>;
export type BillingComponentPeriodEndPlan = Readonly<{
    tag: 'schedule';
    endsAt: string;
}> | Readonly<{
    tag: 'period_end_unavailable';
    currentPeriodEnd: string | null;
}>;
export type BillingComponentTimestampEndPlan = Readonly<{
    tag: 'schedule';
    endsAt: string;
}> | Readonly<{
    tag: 'end_now';
    endsAt: string;
}> | Readonly<{
    tag: 'invalid_end_at';
    endsAt: string | null;
}>;
export type BillingComponentRegistrarAttemptStatus = 'in_flight' | 'provider_unknown' | 'provider_succeeded' | 'provider_succeeded_persist_failed' | 'provider_failed';
export type BillingComponentRegistrarAttemptBlockReason = 'provider_call_in_flight' | 'provider_outcome_unknown' | 'provider_already_succeeded' | 'provider_succeeded_persist_failed' | 'provider_failed';
export type BillingComponentRegistrarAttemptDecision<TAttempt = unknown> = Readonly<{
    tag: 'can_start';
}> | Readonly<{
    tag: 'blocked';
    reason: BillingComponentRegistrarAttemptBlockReason;
    attempt: TAttempt;
}>;
export type ExtraSiteLaunchAcceptedStatus = Extract<BillingComponentPersistenceStatus, 'accepted' | 'sync_failed' | 'active'>;
export type ExtraSiteLaunchComponentContinuation<TComponent> = Readonly<{
    tag: 'accept';
    component: TComponent;
}> | Readonly<{
    tag: 'sync';
    component: TComponent;
}> | Readonly<{
    tag: 'already_active';
    component: TComponent;
}> | Readonly<{
    tag: 'terminal';
    component: TComponent;
}>;
export declare function isEndableBillingComponentStatus(status: BillingComponentPersistenceStatus): status is EndableBillingComponentStatus;
export declare function isEndableBillingAddOnComponent(component: Readonly<{
    kind: BillingComponentKind;
    status: BillingComponentPersistenceStatus;
}>): component is Readonly<{
    kind: EndableBillingComponentKind;
    status: EndableBillingComponentStatus;
}>;
export declare function isActiveOrEndingManagedDomainOverageComponent(component: Readonly<{
    kind: BillingComponentKind;
    status: BillingComponentPersistenceStatus;
}>): component is Readonly<{
    kind: 'managed_domain_overage';
    status: EndableBillingComponentStatus;
}>;
export declare function isFutureTimestamp(timestamp: string, now: Date): boolean;
export declare function isBillingComponentCurrentlyChargeable(component: Readonly<{
    status: BillingComponentPersistenceStatus;
    endsAt: string | null;
}>, now: Date): boolean;
export declare function planBillingComponentEndAtCurrentPeriodEnd(input: Readonly<{
    currentPeriodEnd: string | null;
    now: Date;
}>): BillingComponentPeriodEndPlan;
export declare function planBillingComponentEndAtTimestamp(input: Readonly<{
    endsAt: string | null;
    now: Date;
}>): BillingComponentTimestampEndPlan;
export declare function gbpPenceToAmountCents(amountPence: number, currency: BillingComponentCurrencyCode): number;
export declare function buildMacadamiaExtraSitePricingPolicy(allowance: MacadamiaSiteAllowancePricingInput): ExtraSitePricingPolicy;
export declare function buildManagedDomainRegistrarAttemptIdempotencyKey(input: Readonly<{
    componentId: string;
    domain: string;
    provider: string;
}>): string;
export declare function evaluateBillingComponentRegistrarAttemptDecision<TAttempt extends Readonly<{
    status: BillingComponentRegistrarAttemptStatus;
}>>(attempt: TAttempt | null): BillingComponentRegistrarAttemptDecision<TAttempt>;
export declare function isAcceptedExtraSiteComponentForLaunch(component: Readonly<{
    kind: BillingComponentKind;
    status: BillingComponentPersistenceStatus;
}>): component is Readonly<{
    kind: 'extra_site';
    status: ExtraSiteLaunchAcceptedStatus;
}>;
export declare function classifyExtraSiteLaunchComponentContinuation<TComponent extends Readonly<{
    status: BillingComponentPersistenceStatus;
}>>(component: TComponent): ExtraSiteLaunchComponentContinuation<TComponent>;
export declare function resolveBillableSiteState(input: Readonly<{
    launchedAt: string | null;
    archivedAt?: string | null;
    deletedAt?: string | null;
}>): BillableSiteState;
export declare function classifyBillingModel(input: Readonly<{
    customSitePrices: readonly BillingComponent[];
}>): BillingModelDecision;
export declare function planExtraSiteComponents(input: Readonly<{
    sites: readonly BillableMacadamiaSite[];
    policy: ConfiguredExtraSitePricingPolicy;
    interval?: BillingComponentInterval;
}>): readonly BillingComponent[];
export declare function planMacadamiaExtraSiteReconciliation(input: Readonly<{
    sites: readonly BillableMacadamiaSite[];
    activeExtraSiteComponents: readonly ActiveExtraSiteComponentForReconciliation[];
    acceptedSiteIds?: readonly BillingComponentSiteId[];
    policy: ExtraSitePricingPolicy;
    interval?: BillingComponentInterval;
}>): MacadamiaExtraSiteReconciliationPlan;
export declare function evaluateMacadamiaExtraSiteLaunchDecision(input: Readonly<{
    siteId: BillingComponentSiteId;
    currentPlanId: BillingPlanId;
    currentLiveSiteCount: number;
    acceptedExtraSiteComponents?: readonly Readonly<{
        siteId: BillingComponentSiteId;
        componentId?: BillingComponentId;
    }>[];
    policy: ExtraSitePricingPolicy;
    interval?: BillingComponentInterval;
}>): MacadamiaExtraSiteLaunchDecision;
export declare function macadamiaExtraSiteLaunchDecisionToCreationBillingNotice(decision: MacadamiaExtraSiteLaunchDecision): MacadamiaSiteCreationBillingNotice;
export declare function evaluateMacadamiaSiteCreationBillingNotice(input: Readonly<{
    currentPlanId: BillingPlanId;
    currentLiveSiteCount: number;
    policy: ExtraSitePricingPolicy;
    interval?: BillingComponentInterval;
}>): MacadamiaSiteCreationBillingNotice;
export declare function resolveBillingComponents(input: Readonly<{
    basePlan: BillingComponent;
    customSitePrices: readonly BillingComponent[];
    extraSites?: readonly BillingComponent[];
    recurringAddOns?: readonly BillingComponent[];
}>): BillingComponentResolution;
export declare function partitionPersistedBillingComponents(components: readonly PersistedBillingComponent[]): Readonly<{
    extraSites: readonly PersistedBillingComponent[];
    recurringAddOns: readonly PersistedBillingComponent[];
}>;
export declare function toBillingSiteCostBreakdown(input: Readonly<{
    siteId: string;
    siteName: string;
    monthlyCostCents: number;
    billingStartsAt: string | null;
}>): BillingSiteCostBreakdown;
export declare function planCustomSitePriceComponents(input: Readonly<{
    siteBreakdown: readonly BillingSiteCostBreakdown[];
    currency: BillingComponentCurrencyCode;
    interval: BillingComponentInterval;
}>): readonly BillingComponent[];
export declare function validateBillingComponentCompatibility(input: Readonly<{
    component: BillingComponent;
    requestedInterval: BillingComponentInterval;
    requestedCurrency: BillingComponentCurrencyCode;
}>): BillingComponentCompatibilityMismatch | null;
export declare function planBillingTotalPrice(input: Readonly<{
    planId: string;
    interval: BillingComponentInterval;
    currency: BillingComponentCurrencyCode;
    siteBreakdown: readonly BillingSiteCostBreakdown[];
    persistedComponents: readonly PersistedBillingComponent[];
    basePrice?: BillingBasePricePlan;
}>): BillingTotalPricePlanResult;
export declare function getBillingComponentSummaryLabelRequirements(components: readonly BillingComponent[]): BillingComponentSummaryLabelRequirements;
export declare function buildBillingComponentSummary(input: Readonly<{
    components: readonly BillingComponent[];
    totalCents: number;
    totalCurrency: BillingComponentCurrencyCode;
    isCustomPrice: boolean;
    persistedLabels: ReadonlyMap<string, string>;
    formatAmount: BillingComponentSummaryFormatter;
}>): BillingComponentSummaryResult;
export declare function toBillingComponentSummaryComponent(component: BillingComponent, persistedLabels: ReadonlyMap<string, string>, formatAmount: BillingComponentSummaryFormatter): Readonly<{
    success: true;
    data: BillingComponentSummaryComponent;
} | {
    success: false;
    error: BillingComponentSummaryError;
}>;
export declare function isBillingComponentSummaryBasePlanComponent(component: BillingComponentSummaryComponent): component is BillingComponentSummaryBasePlanComponent;
export declare function isBillingComponentSummarySiteComponent(component: BillingComponentSummaryComponent): component is BillingComponentSummarySiteComponent;
export declare function isBillingComponentSummaryAddOnComponent(component: BillingComponentSummaryComponent): component is BillingComponentSummaryAddOnComponent;
export declare function persistedBillingComponentLabelKey(component: PersistedBillingComponent): string;
export declare function persistedBillingComponentLabelKey(kind: PersistedBillingComponent['kind'], sourceId: string): string;
export declare function parseMacadamiaExtraSitePricingSnapshot(value: unknown): MacadamiaExtraSitePricingSnapshot | null;
export declare function buildMacadamiaExtraSitePricingSnapshot(decision: MacadamiaExtraSiteProposalDecisionPlan): MacadamiaExtraSitePricingSnapshot;
export declare function buildMacadamiaExtraSiteProposalPlan(input: Readonly<{
    billingUserId: string;
    siteId: string;
    decision: MacadamiaExtraSiteProposalDecisionPlan;
}>): MacadamiaExtraSiteBillingComponentProposalPlan;
export type BillingComponentProposalPlanBranding<TIdempotencyKey, TPendingSourceKey, TUserId, TSiteId, TSnapshotHash, TPricingSnapshot> = Readonly<{
    idempotencyKey: (value: string) => TIdempotencyKey;
    pendingSourceKey: (value: string) => TPendingSourceKey;
    userId: (value: string) => TUserId;
    siteId: (value: string) => TSiteId;
    snapshotHash: (value: string) => TSnapshotHash;
    pricingSnapshot: (value: unknown) => TPricingSnapshot;
}>;
export type BillingComponentProposalPricingSnapshotParser<TPricingSnapshot> = (value: unknown) => TPricingSnapshot | null;
export type BrandedBillingComponentProposalPlan<TIdempotencyKey, TPendingSourceKey, TUserId, TSiteId, TSnapshotHash, TPricingSnapshot> = Omit<BillingComponentProposalPlan, 'idempotencyKey' | 'pendingSourceKey' | 'userId' | 'siteId' | 'snapshotHash' | 'pricingSnapshot'> & Readonly<{
    idempotencyKey: TIdempotencyKey;
    pendingSourceKey: TPendingSourceKey;
    userId: TUserId;
    siteId: TSiteId | null;
    snapshotHash: TSnapshotHash;
    pricingSnapshot: TPricingSnapshot;
}>;
export declare function asBillingComponentProposalPlan<TIdempotencyKey, TPendingSourceKey, TUserId, TSiteId, TSnapshotHash, TPricingSnapshot>(plan: BillingComponentProposalPlan, brand: BillingComponentProposalPlanBranding<TIdempotencyKey, TPendingSourceKey, TUserId, TSiteId, TSnapshotHash, TPricingSnapshot>): BrandedBillingComponentProposalPlan<TIdempotencyKey, TPendingSourceKey, TUserId, TSiteId, TSnapshotHash, TPricingSnapshot>;
/**
 * Fail-fast guard for static proposal brand adapters. The parser boundary should
 * be wired during service construction, so returning a Result would only move a
 * programming/configuration error into every runtime caller.
 */
export declare function asBillingComponentProposalPricingSnapshot<TPricingSnapshot>(value: unknown, parse: BillingComponentProposalPricingSnapshotParser<TPricingSnapshot>, description?: string): TPricingSnapshot;
export declare function hashBillingComponentSnapshot(snapshot: unknown): string;
export declare function stableJson(value: unknown): string;
