/**
 * Referral Model
 * Comprehensive referral programme management with rewards, rules, product referrals, and strategies
 */

import mongoose, { Schema, Document } from 'mongoose';

// ============================================
// TYPE DEFINITIONS
// ============================================

export type ReferralOfferType = 'single-sided' | 'double-sided' | 'tiered' | 'affiliate' | 'ambassador' | 'custom';
export type ReferralStatus = 'draft' | 'active' | 'paused' | 'archived';
export type ReferralRewardType = 'discount' | 'credit' | 'cash' | 'free-product' | 'upgrade' | 'gift-card' | 'points' | 'custom';
export type ReferralValueType = 'percentage' | 'fixed' | 'points';
export type ReferralTriggerType = 'signup' | 'purchase' | 'subscription' | 'referral-qualified' | 'milestone' | 'social-share' | 'review';
export type PayoutTiming = 'immediate' | 'on-qualification' | 'monthly' | 'quarterly' | 'annual';
export type FraudPreventionLevel = 'basic' | 'standard' | 'strict' | 'custom';
export type ReferralChannel = 'email' | 'social' | 'link' | 'qr-code' | 'sms' | 'in-app' | 'affiliate' | 'custom';
export type RewardStatus = 'draft' | 'active' | 'sold-out' | 'archived';

// ============================================
// SUB-SCHEMA INTERFACES
// ============================================

export interface IReferralRewardValue {
  value: number;
  valueType: ReferralValueType;
  description?: string;
}

export interface IReferralReward {
  id: string;
  name: string;
  type: ReferralRewardType;
  description?: string;
  referrerReward: IReferralRewardValue;
  refereeReward: IReferralRewardValue;
  tierRestrictions?: string[];
  minimumSpend?: number;
  maximumSpend?: number;
  status: RewardStatus;
  featured?: boolean;
}

export interface IReferralRule {
  id: string;
  name: string;
  trigger: ReferralTriggerType;
  description?: string;
  conditions?: string[];
  rewardReferral?: string;
  rewardReferee?: string;
  qualificationCriteria?: string[];
  cap?: { maxPerUser?: number; maxTotal?: number };
  active: boolean;
  priority?: number;
}

export interface IProductReferral {
  id: string;
  productId?: string;
  productName: string;
  referralBonus?: string;
  conditions?: string[];
  active: boolean;
}

export interface IReferralStrategy {
  channels: ReferralChannel[];
  targetAudience?: string;
  messaging?: string;
  landingPageSuggestions?: string[];
  promotionTips?: string[];
  referralMilestoneRewards?: { milestone: string; reward: string }[];
}

export interface IReferralFraudPrevention {
  level: FraudPreventionLevel;
  maxReferralsPerDay?: number;
  maxReferralsPerIP?: number;
  blockDisposableEmails?: boolean;
}

export interface IReferralNotifications {
  referralSent?: boolean;
  referralQualified?: boolean;
  rewardEarned?: boolean;
  milestoneReached?: boolean;
}

export interface IReferralSettings {
  autoApprove: boolean;
  requireEmailVerification: boolean;
  cooldownPeriodDays?: number;
  fraudPrevention?: IReferralFraudPrevention;
  notifications?: IReferralNotifications;
  expiryDays?: number;
  termsUrl?: string;
}

export interface IMonthlyReferralData {
  month: string;
  referrals: number;
  conversions: number;
}

export interface IReferralMetrics {
  totalReferrals: number;
  activeReferrers: number;
  conversionRate: number;
  rewardsDistributed: number;
  monthlyData: IMonthlyReferralData[];
}

// ============================================
// MAIN INTERFACE
// ============================================

export interface IReferralOffer extends Document {
  // A. Core Information
  name: string;
  slug?: string;
  description?: string;
  type: ReferralOfferType;
  status: ReferralStatus;
  startDate?: Date;
  endDate?: Date;

  // B. Referral Code Configuration
  referralCodePrefix?: string;
  referralCodeFormat?: string;
  maxReferralsPerUser?: number;
  maxTotalReferrals?: number;

  // C. Rewards
  rewards: IReferralReward[];

  // D. Rules
  rules: IReferralRule[];

  // E. Product Referrals
  productReferrals: IProductReferral[];

  // F. Strategies
  strategies?: IReferralStrategy;

  // G. Settings
  settings?: IReferralSettings;

  // H. Payout
  payoutTiming?: PayoutTiming;

  // I. AI Generation
  aiGenerated?: boolean;
  aiPrompt?: string;

  // J. Documents
  termsConditions?: string;
  privacyPolicy?: string;
  faqDocument?: string;
  fullDocument?: string;

  // K. Branding
  programmeLogo?: string;
  primaryColour?: string;
  secondaryColour?: string;

  // L. Stats
  stats?: IReferralMetrics;

  // M. Company Reference
  companyId: string;

  // Timestamps
  createdAt: Date;
  updatedAt: Date;
}

// ============================================
// SUB-SCHEMAS
// ============================================

const ReferralRewardValueSchema = new Schema<IReferralRewardValue>({
  value: { type: Number, default: 0 },
  valueType: { type: String, enum: ['percentage', 'fixed', 'points'], default: 'fixed' },
  description: String,
}, { _id: false });

const ReferralRewardSchema = new Schema<IReferralReward>({
  id: { type: String, required: true },
  name: { type: String, required: true },
  type: {
    type: String,
    enum: ['discount', 'credit', 'cash', 'free-product', 'upgrade', 'gift-card', 'points', 'custom'],
    required: true,
  },
  description: String,
  referrerReward: { type: ReferralRewardValueSchema, default: () => ({}) },
  refereeReward: { type: ReferralRewardValueSchema, default: () => ({}) },
  tierRestrictions: [String],
  minimumSpend: Number,
  maximumSpend: Number,
  status: {
    type: String,
    enum: ['draft', 'active', 'sold-out', 'archived'],
    default: 'draft',
  },
  featured: { type: Boolean, default: false },
}, { _id: false });

const ReferralRuleSchema = new Schema<IReferralRule>({
  id: { type: String, required: true },
  name: { type: String, required: true },
  trigger: {
    type: String,
    enum: ['signup', 'purchase', 'subscription', 'referral-qualified', 'milestone', 'social-share', 'review'],
    required: true,
  },
  description: String,
  conditions: [String],
  rewardReferral: String,
  rewardReferee: String,
  qualificationCriteria: [String],
  cap: {
    maxPerUser: Number,
    maxTotal: Number,
  },
  active: { type: Boolean, default: true },
  priority: Number,
}, { _id: false });

const ProductReferralSchema = new Schema<IProductReferral>({
  id: { type: String, required: true },
  productId: String,
  productName: { type: String, required: true },
  referralBonus: String,
  conditions: [String],
  active: { type: Boolean, default: true },
}, { _id: false });

const ReferralMilestoneRewardSchema = new Schema({
  milestone: String,
  reward: String,
}, { _id: false });

const ReferralStrategySchema = new Schema<IReferralStrategy>({
  channels: [{
    type: String,
    enum: ['email', 'social', 'link', 'qr-code', 'sms', 'in-app', 'affiliate', 'custom'],
  }],
  targetAudience: String,
  messaging: String,
  landingPageSuggestions: [String],
  promotionTips: [String],
  referralMilestoneRewards: [ReferralMilestoneRewardSchema],
}, { _id: false });

const ReferralFraudPreventionSchema = new Schema<IReferralFraudPrevention>({
  level: {
    type: String,
    enum: ['basic', 'standard', 'strict', 'custom'],
    default: 'standard',
  },
  maxReferralsPerDay: Number,
  maxReferralsPerIP: Number,
  blockDisposableEmails: { type: Boolean, default: false },
}, { _id: false });

const ReferralNotificationsSchema = new Schema<IReferralNotifications>({
  referralSent: { type: Boolean, default: true },
  referralQualified: { type: Boolean, default: true },
  rewardEarned: { type: Boolean, default: true },
  milestoneReached: { type: Boolean, default: true },
}, { _id: false });

const ReferralSettingsSchema = new Schema<IReferralSettings>({
  autoApprove: { type: Boolean, default: false },
  requireEmailVerification: { type: Boolean, default: true },
  cooldownPeriodDays: Number,
  fraudPrevention: { type: ReferralFraudPreventionSchema, default: () => ({}) },
  notifications: { type: ReferralNotificationsSchema, default: () => ({}) },
  expiryDays: Number,
  termsUrl: String,
}, { _id: false });

const MonthlyReferralDataSchema = new Schema<IMonthlyReferralData>({
  month: { type: String, required: true },
  referrals: { type: Number, default: 0 },
  conversions: { type: Number, default: 0 },
}, { _id: false });

const ReferralMetricsSchema = new Schema<IReferralMetrics>({
  totalReferrals: { type: Number, default: 0 },
  activeReferrers: { type: Number, default: 0 },
  conversionRate: { type: Number, default: 0 },
  rewardsDistributed: { type: Number, default: 0 },
  monthlyData: [MonthlyReferralDataSchema],
}, { _id: false });

// ============================================
// MAIN SCHEMA
// ============================================

const ReferralOfferSchema = new Schema<IReferralOffer>({
  // A. Core Information
  name: {
    type: String,
    required: [true, 'Referral offer name is required'],
    trim: true,
    maxlength: [200, 'Referral offer name cannot exceed 200 characters'],
  },
  slug: { type: String, trim: true, lowercase: true },
  description: { type: String, trim: true },
  type: {
    type: String,
    enum: ['single-sided', 'double-sided', 'tiered', 'affiliate', 'ambassador', 'custom'],
    default: 'single-sided',
  },
  status: {
    type: String,
    enum: ['draft', 'active', 'paused', 'archived'],
    default: 'draft',
  },
  startDate: Date,
  endDate: Date,

  // B. Referral Code Configuration
  referralCodePrefix: { type: String, trim: true },
  referralCodeFormat: { type: String, trim: true },
  maxReferralsPerUser: Number,
  maxTotalReferrals: Number,

  // C. Rewards
  rewards: [ReferralRewardSchema],

  // D. Rules
  rules: [ReferralRuleSchema],

  // E. Product Referrals
  productReferrals: [ProductReferralSchema],

  // F. Strategies
  strategies: ReferralStrategySchema,

  // G. Settings
  settings: ReferralSettingsSchema,

  // H. Payout
  payoutTiming: {
    type: String,
    enum: ['immediate', 'on-qualification', 'monthly', 'quarterly', 'annual'],
    default: 'immediate',
  },

  // I. AI Generation
  aiGenerated: { type: Boolean, default: false },
  aiPrompt: String,

  // J. Documents
  termsConditions: String,
  privacyPolicy: String,
  faqDocument: String,
  fullDocument: String,

  // K. Branding
  programmeLogo: String,
  primaryColour: String,
  secondaryColour: String,

  // L. Stats
  stats: ReferralMetricsSchema,

  // M. Company Reference
  companyId: {
    type: String,
    required: [true, 'Company ID is required'],
    index: true,
  },
}, {
  timestamps: true,
});

// ============================================
// INDEXES
// ============================================

ReferralOfferSchema.index({ companyId: 1, status: 1 });
ReferralOfferSchema.index({ companyId: 1, type: 1 });
ReferralOfferSchema.index({ companyId: 1, slug: 1 }, { unique: true });
ReferralOfferSchema.index({ name: 'text', description: 'text' });

// ============================================
// PRE-SAVE HOOK
// ============================================

ReferralOfferSchema.pre('save', async function (this: IReferralOffer) {
  if (this.isModified('name') || !this.slug) {
    const baseSlug = this.name
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
    let slug = baseSlug;
    let suffix = 1;
    const ReferralOffer = this.constructor as any;
    while (await ReferralOffer.exists({ companyId: this.companyId, slug, _id: { $ne: this._id } })) {
      slug = `${baseSlug}-${suffix++}`;
    }
    this.slug = slug;
  }
});

// ============================================
// EXPORT
// ============================================

export const ReferralOffer = mongoose.model<IReferralOffer>('ReferralOffer', ReferralOfferSchema);