/**
 * CashFlowProjection Entity - Proyecciones de Flujo de Efectivo
 *
 * Registro de proyecciones y flujo real por periodo.
 *
 * @module Finance
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
} from 'typeorm';

export type CashFlowType = 'projected' | 'actual' | 'comparison';
export type CashFlowPeriodType = 'daily' | 'weekly' | 'monthly' | 'quarterly';
export type CashFlowCategory =
  | 'operating_income'
  | 'operating_expense'
  | 'investing_income'
  | 'investing_expense'
  | 'financing_income'
  | 'financing_expense';

@Entity('cash_flow_projections', { schema: 'finance' })
@Index(['tenantId', 'projectId'])
@Index(['tenantId', 'periodStart', 'periodEnd'])
@Index(['tenantId', 'flowType'])
export class CashFlowProjection {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  @Index()
  tenantId!: string;

  // Tipo de flujo
  @Column({
    name: 'flow_type',
    type: 'enum',
    enum: ['projected', 'actual', 'comparison'],
    enumName: 'cash_flow_type',
  })
  flowType!: CashFlowType;

  @Column({
    name: 'period_type',
    type: 'enum',
    enum: ['daily', 'weekly', 'monthly', 'quarterly'],
    enumName: 'cash_flow_period_type',
    default: 'weekly',
  })
  periodType!: CashFlowPeriodType;

  // Periodo
  @Column({ name: 'period_start', type: 'date' })
  periodStart!: Date;

  @Column({ name: 'period_end', type: 'date' })
  periodEnd!: Date;

  @Column({ name: 'fiscal_year', type: 'int' })
  fiscalYear!: number;

  @Column({ name: 'fiscal_period', type: 'int' })
  fiscalPeriod!: number;

  // Proyecto (opcional, si es por proyecto)
  @Column({ name: 'project_id', type: 'uuid', nullable: true })
  projectId?: string;

  @Column({ name: 'project_code', length: 50, nullable: true })
  projectCode?: string;

  // Saldo inicial
  @Column({
    name: 'opening_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  openingBalance!: number;

  // INGRESOS OPERATIVOS
  @Column({
    name: 'income_estimations',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  incomeEstimations!: number;

  @Column({
    name: 'income_sales',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  incomeSales!: number;

  @Column({
    name: 'income_advances',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  incomeAdvances!: number;

  @Column({
    name: 'income_other',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  incomeOther!: number;

  @Column({
    name: 'total_income',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  totalIncome!: number;

  // EGRESOS OPERATIVOS
  @Column({
    name: 'expense_suppliers',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expenseSuppliers!: number;

  @Column({
    name: 'expense_subcontractors',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expenseSubcontractors!: number;

  @Column({
    name: 'expense_payroll',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expensePayroll!: number;

  @Column({
    name: 'expense_taxes',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expenseTaxes!: number;

  @Column({
    name: 'expense_operating',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expenseOperating!: number;

  @Column({
    name: 'expense_other',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  expenseOther!: number;

  @Column({
    name: 'total_expenses',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  totalExpenses!: number;

  // FLUJO NETO OPERATIVO
  @Column({
    name: 'net_operating_flow',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  netOperatingFlow!: number;

  // INVERSIÓN
  @Column({
    name: 'investing_income',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  investingIncome!: number;

  @Column({
    name: 'investing_expense',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  investingExpense!: number;

  @Column({
    name: 'net_investing_flow',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  netInvestingFlow!: number;

  // FINANCIAMIENTO
  @Column({
    name: 'financing_income',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  financingIncome!: number;

  @Column({
    name: 'financing_expense',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  financingExpense!: number;

  @Column({
    name: 'net_financing_flow',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  netFinancingFlow!: number;

  // TOTALES
  @Column({
    name: 'net_cash_flow',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  netCashFlow!: number;

  @Column({
    name: 'closing_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  closingBalance!: number;

  // Varianza (para comparaciones)
  @Column({
    name: 'projected_amount',
    type: 'decimal',
    precision: 18,
    scale: 2,
    nullable: true,
  })
  projectedAmount?: number;

  @Column({
    name: 'actual_amount',
    type: 'decimal',
    precision: 18,
    scale: 2,
    nullable: true,
  })
  actualAmount?: number;

  @Column({
    name: 'variance_amount',
    type: 'decimal',
    precision: 18,
    scale: 2,
    nullable: true,
  })
  varianceAmount?: number;

  @Column({
    name: 'variance_percentage',
    type: 'decimal',
    precision: 8,
    scale: 2,
    nullable: true,
  })
  variancePercentage?: number;

  // Desglose detallado (JSON)
  @Column({ name: 'income_breakdown', type: 'jsonb', nullable: true })
  incomeBreakdown?: Record<string, any>[];

  @Column({ name: 'expense_breakdown', type: 'jsonb', nullable: true })
  expenseBreakdown?: Record<string, any>[];

  // Estado
  @Column({ name: 'is_locked', type: 'boolean', default: false })
  isLocked!: boolean;

  @Column({ name: 'locked_at', type: 'timestamptz', nullable: true })
  lockedAt?: Date;

  // Notas y metadatos
  @Column({ type: 'text', nullable: true })
  notes?: string;

  @Column({ name: 'variance_notes', type: 'text', nullable: true })
  varianceNotes?: string;

  @Column({ type: 'jsonb', nullable: true })
  metadata?: Record<string, any>;

  // Auditoría
  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy?: string;

  @Column({ name: 'updated_by', type: 'uuid', nullable: true })
  updatedBy?: string;

  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt!: Date;

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
  updatedAt!: Date;

  @Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
  deletedAt?: Date;
}
