/**
 * Company Subscription Model
 * Tracks each company's subscription status, billing, and limit overrides.
 */

import mongoose, { Schema, Document } from 'mongoose';

export type SubscriptionStatus = 'trial' | 'active' | 'expired' | 'cancelled' | 'pending_payment' | 'suspended';
export type BillingCycle = 'monthly' | 'quarterly' | 'half_yearly' | 'yearly' | 'lifetime';
export type PaymentGateway = 'stripe' | 'razorpay' | 'manual';

export interface ICompanySubscription extends Document {
  companyId: string;
  packageId: string;
  status: SubscriptionStatus;
  billingCycle: BillingCycle;
  startDate: Date;
  endDate: Date;
  trialEndDate?: Date;
  currency: string;
  paymentGateway: PaymentGateway;
  stripeCustomerId?: string;
  stripeSubscriptionId?: string;
  razorpaySubscriptionId?: string;
  autoRenew: boolean;
  currentPeriodStart?: Date;
  currentPeriodEnd?: Date;
  cancelledAt?: Date;
  limitOverrides?: Partial<ILimitOverrides>;
  notes?: string;
  isLifetime: boolean;
  /**
   * True when this subscription was taken on the dedicated Free Trial package.
   * Recorded on the subscription (not derived from the package) so the
   * "one free trial per company" rule survives the trial package being
   * renamed, deactivated or replaced.
   */
  isFreeTrial: boolean;
  // Package assignment — snapshotted from SubscriptionPackage at purchase time
  modules: string[];      // PricingItem slugs with categorySlug='modules'
  features: string[];     // PricingItem slugs with categorySlug='ai_features' + package.features
  aiModels: string[];     // PricingItem slugs with categorySlug='ai_models'
  // Coupon applied at checkout (Coupon Management) — recorded so payment
  // verification can commit the redemption with the real amounts.
  appliedCouponCode?: string;
  couponDiscountAmount?: number;
  // Dynamic pricing engine fields
  selectedPricingItemSlugs?: string[];
  selectedAddonSlugs?: string[];
  appliedDiscountCodes?: string[];
  pricingSnapshot?: {
    items: { slug: string; name: string; price: number }[];
    addons: { slug: string; name: string; price: number }[];
    discounts: { code: string; name: string; amount: number }[];
    subtotal: number;
    tax: number;
    total: number;
    currency: string;
    billingCycle: string;
  };
  createdAt: Date;
  updatedAt: Date;
}

export interface ILimitOverrides {
  companies: number;
  campaigns: number;
  products: number;
  influencers: number;
  prCampaigns: number;
  // Module-based limits
  founders: number;
  employees: number;
  icps: number;
  personas: number;
  competitors: number;
  blogs: number;
  caseStudies: number;
  testimonials: number;
  landingPages: number;
  salesScripts: number;
  salesCollateral: number;
  videoContent: number;
  books: number;
  adCampaigns: number;
  emailTemplates: number;
  courses: number;
  events: number;
  loyaltyProgrammes: number;
  membershipPlans: number;
  referralProgrammes: number;
  sops: number;
  jobPostings: number;
  legalDocuments: number;
  seoPages: number;
  gmbLocations: number;
  websitePlanners: number;
  // Funding module limits
  pitchDecks: number;
  financialModels: number;
  investors: number;
  fundingRounds: number;
  // New module limits
  businessProfiles: number;
  newsletters: number;
  faqs: number;
  hrAssets: number;
  stationeryItems: number;
  introScripts: number;
  socialMediaPosts: number;
}

const LimitOverridesSchema = new Schema<ILimitOverrides>({
  companies: { type: Number },
  campaigns: { type: Number },
  products: { type: Number },
  influencers: { type: Number },
  prCampaigns: { type: Number },
  // Module-based limits
  founders: { type: Number },
  employees: { type: Number },
  icps: { type: Number },
  personas: { type: Number },
  competitors: { type: Number },
  blogs: { type: Number },
  caseStudies: { type: Number },
  testimonials: { type: Number },
  landingPages: { type: Number },
  salesScripts: { type: Number },
  salesCollateral: { type: Number },
  videoContent: { type: Number },
  books: { type: Number },
  adCampaigns: { type: Number },
  emailTemplates: { type: Number },
  courses: { type: Number },
  events: { type: Number },
  loyaltyProgrammes: { type: Number },
  membershipPlans: { type: Number },
  referralProgrammes: { type: Number },
  sops: { type: Number },
  jobPostings: { type: Number },
  legalDocuments: { type: Number },
  seoPages: { type: Number },
  gmbLocations: { type: Number },
  websitePlanners: { type: Number },
  // Funding module limits
  pitchDecks: { type: Number },
  financialModels: { type: Number },
  investors: { type: Number },
  fundingRounds: { type: Number },
  // New module limits
  businessProfiles: { type: Number },
  newsletters: { type: Number },
  faqs: { type: Number },
  hrAssets: { type: Number },
  stationeryItems: { type: Number },
  introScripts: { type: Number },
  socialMediaPosts: { type: Number },
}, { _id: false });

const CompanySubscriptionSchema = new Schema<ICompanySubscription>({
  companyId: {
    type: String,
    required: [true, 'Company ID is required'],
    unique: true,
    index: true,
  },
  packageId: {
    type: String,
    required: [true, 'Package ID is required'],
  },
  status: {
    type: String,
    enum: ['trial', 'active', 'expired', 'cancelled', 'pending_payment', 'suspended'],
    default: 'pending_payment',
  },
  billingCycle: {
    type: String,
    enum: ['monthly', 'quarterly', 'half_yearly', 'yearly', 'lifetime'],
    default: 'monthly',
  },
  startDate: {
    type: Date,
    required: [true, 'Start date is required'],
  },
  endDate: {
    type: Date,
    required: [true, 'End date is required'],
  },
  trialEndDate: {
    type: Date,
  },
  currency: {
    type: String,
    enum: ['USD', 'INR', 'AED'],
    default: 'USD',
  },
  paymentGateway: {
    type: String,
    enum: ['stripe', 'razorpay', 'manual'],
    default: 'manual',
  },
  stripeCustomerId: {
    type: String,
    sparse: true,
  },
  stripeSubscriptionId: {
    type: String,
    sparse: true,
  },
  razorpaySubscriptionId: {
    type: String,
    sparse: true,
  },
  autoRenew: {
    type: Boolean,
    default: true,
  },
  currentPeriodStart: {
    type: Date,
  },
  currentPeriodEnd: {
    type: Date,
  },
  cancelledAt: {
    type: Date,
  },
  limitOverrides: {
    type: LimitOverridesSchema,
    default: undefined,
  },
  notes: {
    type: String,
    trim: true,
    maxlength: [5000, 'Notes cannot exceed 5000 characters'],
  },
  isLifetime: {
    type: Boolean,
    default: false,
  },
  isFreeTrial: {
    type: Boolean,
    default: false,
  },
  // Package assignment — snapshotted from SubscriptionPackage at purchase time
  modules: [{
    type: String,
    trim: true,
  }],
  features: [{
    type: String,
    trim: true,
  }],
  aiModels: [{
    type: String,
    trim: true,
  }],
  // Coupon applied at checkout (Coupon Management)
  appliedCouponCode: {
    type: String,
    trim: true,
    uppercase: true,
  },
  couponDiscountAmount: {
    type: Number,
    min: 0,
  },
  // Dynamic pricing engine fields
  selectedPricingItemSlugs: [{
    type: String,
    trim: true,
    lowercase: true,
  }],
  selectedAddonSlugs: [{
    type: String,
    trim: true,
    lowercase: true,
  }],
  appliedDiscountCodes: [{
    type: String,
    trim: true,
    uppercase: true,
  }],
  pricingSnapshot: {
    type: Schema.Types.Mixed,
    default: null,
  },
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

CompanySubscriptionSchema.index({ companyId: 1 }, { unique: true });
CompanySubscriptionSchema.index({ status: 1 });
CompanySubscriptionSchema.index({ packageId: 1 });

export const CompanySubscription = mongoose.models.CompanySubscription || mongoose.model<ICompanySubscription>('CompanySubscription', CompanySubscriptionSchema);