/**
 * BidBudget Entity - Presupuesto de Licitación
 *
 * Desglose del presupuesto para la propuesta económica.
 *
 * @module Bidding
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  JoinColumn,
  Index,
} from 'typeorm';
import { Bid } from './bid.entity';

export type BudgetItemType =
  | 'direct_cost'
  | 'indirect_cost'
  | 'labor'
  | 'materials'
  | 'equipment'
  | 'subcontract'
  | 'overhead'
  | 'profit'
  | 'contingency'
  | 'financing'
  | 'taxes'
  | 'bonds'
  | 'other';

export type BudgetStatus = 'draft' | 'calculated' | 'reviewed' | 'approved' | 'locked';

@Entity('bid_budget', { schema: 'bidding' })
@Index(['tenantId', 'bidId'])
@Index(['tenantId', 'itemType'])
export class BidBudget {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

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

  // Referencia a licitación
  @Column({ name: 'bid_id', type: 'uuid' })
  bidId!: string;

  @ManyToOne(() => Bid, (bid) => bid.budgetItems)
  @JoinColumn({ name: 'bid_id' })
  bid?: Bid;

  // Jerarquía
  @Column({ name: 'parent_id', type: 'uuid', nullable: true })
  parentId?: string;

  @Column({ name: 'sort_order', type: 'int', default: 0 })
  sortOrder!: number;

  @Column({ type: 'int', default: 0 })
  level!: number;

  @Column({ length: 50 })
  code!: string;

  // Información del item
  @Column({ length: 255 })
  name!: string;

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

  @Column({
    name: 'item_type',
    type: 'enum',
    enum: ['direct_cost', 'indirect_cost', 'labor', 'materials', 'equipment', 'subcontract', 'overhead', 'profit', 'contingency', 'financing', 'taxes', 'bonds', 'other'],
    enumName: 'bid_budget_item_type',
  })
  itemType!: BudgetItemType;

  @Column({
    type: 'enum',
    enum: ['draft', 'calculated', 'reviewed', 'approved', 'locked'],
    enumName: 'bid_budget_status',
    default: 'draft',
  })
  status!: BudgetStatus;

  // Unidad y cantidad
  @Column({ length: 20, nullable: true })
  unit?: string;

  @Column({
    type: 'decimal',
    precision: 18,
    scale: 4,
    default: 0,
  })
  quantity!: number;

  // Precios
  @Column({
    name: 'unit_price',
    type: 'decimal',
    precision: 18,
    scale: 4,
    default: 0,
  })
  unitPrice!: number;

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

  // Desglose de costos directos
  @Column({
    name: 'materials_cost',
    type: 'decimal',
    precision: 18,
    scale: 2,
    nullable: true,
  })
  materialsCost?: number;

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

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

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

  // Porcentajes
  @Column({
    name: 'indirect_percentage',
    type: 'decimal',
    precision: 5,
    scale: 2,
    nullable: true,
  })
  indirectPercentage?: number;

  @Column({
    name: 'profit_percentage',
    type: 'decimal',
    precision: 5,
    scale: 2,
    nullable: true,
  })
  profitPercentage?: number;

  @Column({
    name: 'financing_percentage',
    type: 'decimal',
    precision: 5,
    scale: 2,
    nullable: true,
  })
  financingPercentage?: number;

  // Comparación con base de licitación
  @Column({
    name: 'base_amount',
    type: 'decimal',
    precision: 18,
    scale: 2,
    nullable: true,
  })
  baseAmount?: 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;

  // Flags
  @Column({ name: 'is_summary', type: 'boolean', default: false })
  isSummary!: boolean;

  @Column({ name: 'is_calculated', type: 'boolean', default: false })
  isCalculated!: boolean;

  @Column({ name: 'is_adjusted', type: 'boolean', default: false })
  isAdjusted!: boolean;

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

  // Referencia a concepto de catálogo
  @Column({ name: 'catalog_concept_id', type: 'uuid', nullable: true })
  catalogConceptId?: string;

  // Notas y metadatos
  @Column({ type: 'text', nullable: true })
  notes?: 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;
}
