/**
 * Funding Round Model
 *
 * Track funding rounds, commitments, valuations, and round progress.
 */

import mongoose, { Schema, Document, models, Model } from 'mongoose';

// ============================================
// TYPES
// ============================================

export type RoundStatus = 'planning' | 'active' | 'committed' | 'closed' | 'cancelled';
export type RoundType = 'pre-seed' | 'seed' | 'series-a' | 'series-b' | 'series-c' | 'series-d' | 'extension' | 'bridge' | 'debt';
export type CommitmentStatus = 'verbal' | 'term-sheet' | 'signed' | 'wired';

export interface ICommitment {
  id: string;
  investorId: string;
  investorName: string;
  amount: number;
  equity?: number;
  status: CommitmentStatus;
  committedDate?: string;
  notes?: string;
}

export interface IRoundTerms {
  valuationCap?: number;
  discount?: number;
  proRata?: boolean;
  boardSeats?: number;
  observerSeats?: number;
  liquidationPreference?: '1x' | '1.5x' | '2x';
  antiDilution?: 'full-ratchet' | 'weighted-average' | 'none';
  notes?: string;
}

export interface IRoundDocument {
  id: string;
  name: string;
  type: 'term-sheet' | 'cap-table' | 'pitch-deck' | 'financials' | 'other';
  url: string;
  uploadedAt: Date;
}

export interface IFundingRound extends Document {
  companyId: string;
  name: string;
  type: RoundType;
  status: RoundStatus;
  targetAmount: number;
  minInvestment?: number;
  maxInvestment?: number;
  preMoneyValuation?: number;
  postMoneyValuation?: number;
  equityOffered?: number;
  targetCloseDate?: string;
  actualCloseDate?: string;
  commitments: ICommitment[];
  totalCommitted: number;
  terms?: IRoundTerms;
  documents?: IRoundDocument[];
  pitchDeckId?: string;
  financialModelId?: string;
  createdBy: string;
  createdAt: Date;
  updatedAt: Date;
}

// ============================================
// SCHEMA
// ============================================

const CommitmentSchema = new Schema<ICommitment>(
  {
    id: { type: String, required: true },
    investorId: { type: String, required: true },
    investorName: { type: String, required: true },
    amount: { type: Number, required: true, min: 0 },
    equity: { type: Number, min: 0, max: 100 },
    status: {
      type: String,
      enum: ['verbal', 'term-sheet', 'signed', 'wired'],
      default: 'verbal',
    },
    committedDate: { type: String },
    notes: { type: String },
  },
  { _id: false }
);

const RoundTermsSchema = new Schema<IRoundTerms>(
  {
    valuationCap: { type: Number },
    discount: { type: Number },
    proRata: { type: Boolean, default: true },
    boardSeats: { type: Number, default: 0 },
    observerSeats: { type: Number, default: 0 },
    liquidationPreference: {
      type: String,
      enum: ['1x', '1.5x', '2x'],
      default: '1x',
    },
    antiDilution: {
      type: String,
      enum: ['full-ratchet', 'weighted-average', 'none'],
      default: 'weighted-average',
    },
    notes: { type: String },
  },
  { _id: false }
);

const RoundDocumentSchema = new Schema<IRoundDocument>(
  {
    id: { type: String, required: true },
    name: { type: String, required: true },
    type: {
      type: String,
      enum: ['term-sheet', 'cap-table', 'pitch-deck', 'financials', 'other'],
      required: true,
    },
    url: { type: String, required: true },
    uploadedAt: { type: Date, default: Date.now },
  },
  { _id: false }
);

const FundingRoundSchema = new Schema<IFundingRound>(
  {
    companyId: { type: String, required: true, index: true },
    name: { type: String, required: true, maxlength: 200 },
    type: {
      type: String,
      enum: ['pre-seed', 'seed', 'series-a', 'series-b', 'series-c', 'series-d', 'extension', 'bridge', 'debt'],
      required: true,
    },
    status: {
      type: String,
      enum: ['planning', 'active', 'committed', 'closed', 'cancelled'],
      default: 'planning',
    },
    targetAmount: { type: Number, required: true, min: 0 },
    minInvestment: { type: Number, min: 0 },
    maxInvestment: { type: Number, min: 0 },
    preMoneyValuation: { type: Number, min: 0 },
    postMoneyValuation: { type: Number, min: 0 },
    equityOffered: { type: Number, min: 0, max: 100 },
    targetCloseDate: { type: String },
    actualCloseDate: { type: String },
    commitments: [CommitmentSchema],
    totalCommitted: { type: Number, default: 0, min: 0 },
    terms: RoundTermsSchema,
    documents: [RoundDocumentSchema],
    pitchDeckId: { type: String },
    financialModelId: { type: String },
    createdBy: { type: String, required: true },
  },
  { timestamps: true }
);

// Indexes
FundingRoundSchema.index({ companyId: 1, status: 1 });
FundingRoundSchema.index({ companyId: 1, type: 1 });
FundingRoundSchema.index({ companyId: 1, createdAt: -1 });

// Pre-save hook to calculate totalCommitted
FundingRoundSchema.pre('save', function (next) {
  if (this.commitments && Array.isArray(this.commitments)) {
    this.totalCommitted = this.commitments.reduce((sum, c) => sum + (c.amount || 0), 0);
  }
  next();
});

// ============================================
// MODEL
// ============================================

export const FundingRound: Model<IFundingRound> =
  models.FundingRound || mongoose.model<IFundingRound>('FundingRound', FundingRoundSchema);

export default FundingRound;