import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { HydratedDocument, Types } from 'mongoose'

export type SubscriptionDocument = HydratedDocument<Subscription>

export type SubscriptionStatus =
  | 'trialing'
  | 'active'
  | 'past_due'
  | 'canceled'
  | 'incomplete'
  | 'incomplete_expired'

@Schema({ collection: 'subscriptions', timestamps: true })
export class Subscription {
  @Prop({ type: Types.ObjectId, ref: 'Tenant', required: true, unique: true, index: true })
  tenantId!: Types.ObjectId

  @Prop({ enum: ['mvp', 'pro', 'enterprise'], default: 'mvp' })
  plan!: 'mvp' | 'pro' | 'enterprise'

  // Billing cycle. Carried alongside plan so MRR aggregation doesn't have
  // to walk to the Price doc just to normalise to monthly.
  @Prop({ enum: ['monthly', 'quarterly', 'yearly'], default: 'monthly' })
  cycle!: 'monthly' | 'quarterly' | 'yearly'

  // Currency the customer is billed in. Snapshotted from the wizard so a
  // later catalog edit that adds/removes currencies doesn't change what
  // this customer pays. MRR aggregation groups by this field.
  @Prop({ enum: ['DKK', 'EUR', 'USD'], default: 'DKK', index: true })
  currency!: 'DKK' | 'EUR' | 'USD'

  // The catalog row this sub was provisioned against. Sparse — Enterprise
  // (custom pricing) and pre-billing-pipeline tenants leave this empty,
  // which MRR aggregation treats as "0 / custom".
  @Prop({ type: Types.ObjectId, ref: 'Price', index: true, sparse: true })
  priceId?: Types.ObjectId

  // Snapshot of the per-seat amount in `currency` at provision time. Lets
  // MRR aggregation compute without re-reading the Price doc, and keeps
  // the historical bill stable when the operator edits the catalog later.
  @Prop({ type: Number, min: 0, default: 0 })
  perSeatAmount!: number

  // Snapshot of the seat count at provision time. Updated when the
  // operator/partner changes seats — we don't recompute from Tenant.seats
  // on each MRR aggregation so a mid-cycle seat change is visible
  // immediately without waiting for the next renewal.
  @Prop({ type: Number, min: 0, default: 0 })
  seats!: number

  @Prop({
    enum: ['trialing', 'active', 'past_due', 'canceled', 'incomplete', 'incomplete_expired'],
    default: 'trialing',
    index: true,
  })
  status!: SubscriptionStatus

  // Stripe references — populated when Phase 4 wires the billing flow. Not used yet.
  @Prop({ index: true, sparse: true })
  stripeCustomerId?: string

  @Prop({ index: true, sparse: true })
  stripeSubscriptionId?: string

  @Prop()
  trialEndsAt?: Date

  @Prop()
  currentPeriodEnd?: Date

  @Prop()
  canceledAt?: Date
}

export const SubscriptionSchema = SchemaFactory.createForClass(Subscription)
