/**
 * Financial Model
 *
 * Revenue forecasts, P&L statements, cash flow, unit economics, and scenario planning.
 */

import mongoose, { Schema, Document, models, Model } from 'mongoose';

// ============================================
// TYPES
// ============================================

export type ModelStatus = 'draft' | 'in-review' | 'approved' | 'archived';
export type RevenueType = 'subscription' | 'transaction' | 'usage-based' | 'licensing' | 'hybrid';
export type ScenarioType = 'base' | 'conservative' | 'optimistic' | 'custom';
export type CostType = 'cogs' | 'opex' | 'capex';

export interface IRevenueStream {
  id: string;
  name: string;
  type: RevenueType;
  monthlyValues: Record<string, number>;
  growthRate?: number;
  assumptions?: string;
}

export interface ICostCategory {
  id: string;
  name: string;
  type: CostType;
  monthlyValues: Record<string, number>;
  assumptions?: string;
  isFixed: boolean;
}

export interface IUnitEconomics {
  cac: number;
  ltv: number;
  ltvCacRatio: number;
  paybackPeriod: number;
  arpu: number;
  grossMargin: number;
  churnRate: number;
  customerLifetime: number;
  cacPaybackMonths: number;
}

export interface IHeadcountPlanEntry {
  role: string;
  department: string;
  count: number;
  avgSalary: number;
  startDate?: string;
}

export interface IFundingAssumptions {
  currentCash?: number;
  monthlyBurn?: number;
  runwayMonths?: number;
  fundingDate?: string;
}

export interface IFinancialScenario {
  id: string;
  name: string;
  type: ScenarioType;
  adjustments: Record<string, number>;
  notes?: string;
}

export interface IAINarrative {
  summary?: string;
  keyInsights?: string[];
  risks?: string[];
  opportunities?: string[];
  generatedAt?: Date;
}

export interface IFinancialModel extends Document {
  companyId: string;
  name: string;
  description?: string;
  status: ModelStatus;
  startDate: string;
  endDate: string;
  fiscalYearStart: number;
  currency: string;
  revenueStreams: IRevenueStream[];
  costs: ICostCategory[];
  unitEconomics: IUnitEconomics;
  headcountPlan?: IHeadcountPlanEntry[];
  fundingAssumptions?: IFundingAssumptions;
  scenarios: IFinancialScenario[];
  activeScenarioId?: string;
  aiNarrative?: IAINarrative;
  linkedData?: {
    businessProfileId?: string;
    productIds?: string[];
  };
  createdBy: string;
  createdAt: Date;
  updatedAt: Date;
}

// ============================================
// SCHEMA
// ============================================

const RevenueStreamSchema = new Schema<IRevenueStream>(
  {
    id: { type: String, required: true },
    name: { type: String, required: true },
    type: {
      type: String,
      enum: ['subscription', 'transaction', 'usage-based', 'licensing', 'hybrid'],
      required: true,
    },
    monthlyValues: { type: Schema.Types.Mixed, default: {} },
    growthRate: { type: Number },
    assumptions: { type: String },
  },
  { _id: false }
);

const CostCategorySchema = new Schema<ICostCategory>(
  {
    id: { type: String, required: true },
    name: { type: String, required: true },
    type: {
      type: String,
      enum: ['cogs', 'opex', 'capex'],
      required: true,
    },
    monthlyValues: { type: Schema.Types.Mixed, default: {} },
    assumptions: { type: String },
    isFixed: { type: Boolean, default: false },
  },
  { _id: false }
);

const UnitEconomicsSchema = new Schema<IUnitEconomics>(
  {
    cac: { type: Number, default: 0 },
    ltv: { type: Number, default: 0 },
    ltvCacRatio: { type: Number, default: 0 },
    paybackPeriod: { type: Number, default: 0 },
    arpu: { type: Number, default: 0 },
    grossMargin: { type: Number, default: 0 },
    churnRate: { type: Number, default: 0 },
    customerLifetime: { type: Number, default: 0 },
    cacPaybackMonths: { type: Number, default: 0 },
  },
  { _id: false }
);

const HeadcountPlanSchema = new Schema<IHeadcountPlanEntry>(
  {
    role: { type: String, required: true },
    department: { type: String, required: true },
    count: { type: Number, default: 1 },
    avgSalary: { type: Number, default: 0 },
    startDate: { type: String },
  },
  { _id: false }
);

const FundingAssumptionsSchema = new Schema<IFundingAssumptions>(
  {
    currentCash: { type: Number },
    monthlyBurn: { type: Number },
    runwayMonths: { type: Number },
    fundingDate: { type: String },
  },
  { _id: false }
);

const ScenarioSchema = new Schema<IFinancialScenario>(
  {
    id: { type: String, required: true },
    name: { type: String, required: true },
    type: {
      type: String,
      enum: ['base', 'conservative', 'optimistic', 'custom'],
      required: true,
    },
    adjustments: { type: Schema.Types.Mixed, default: {} },
    notes: { type: String },
  },
  { _id: false }
);

const AINarrativeSchema = new Schema<IAINarrative>(
  {
    summary: { type: String },
    keyInsights: [{ type: String }],
    risks: [{ type: String }],
    opportunities: [{ type: String }],
    generatedAt: { type: Date },
  },
  { _id: false }
);

const LinkedDataSchema = new Schema(
  {
    businessProfileId: { type: String },
    productIds: [{ type: String }],
  },
  { _id: false }
);

const FinancialModelSchema = new Schema<IFinancialModel>(
  {
    companyId: { type: String, required: true, index: true },
    name: { type: String, required: true, maxlength: 200 },
    description: { type: String, maxlength: 2000 },
    status: {
      type: String,
      enum: ['draft', 'in-review', 'approved', 'archived'],
      default: 'draft',
    },
    startDate: { type: String, required: true },
    endDate: { type: String, required: true },
    fiscalYearStart: { type: Number, default: 1, min: 1, max: 12 },
    currency: { type: String, default: 'USD' },
    revenueStreams: [RevenueStreamSchema],
    costs: [CostCategorySchema],
    unitEconomics: { type: UnitEconomicsSchema, default: () => ({}) },
    headcountPlan: [HeadcountPlanSchema],
    fundingAssumptions: FundingAssumptionsSchema,
    scenarios: [ScenarioSchema],
    activeScenarioId: { type: String },
    aiNarrative: AINarrativeSchema,
    linkedData: LinkedDataSchema,
    createdBy: { type: String, required: true },
  },
  { timestamps: true }
);

// Indexes
FinancialModelSchema.index({ companyId: 1, status: 1 });
FinancialModelSchema.index({ companyId: 1, createdAt: -1 });

// ============================================
// MODEL
// ============================================

export const FinancialModel: Model<IFinancialModel> =
  models.FinancialModel || mongoose.model<IFinancialModel>('FinancialModel', FinancialModelSchema);

export default FinancialModel;