/**
 * Tender Entity - Licitaciones Formales
 * Representa una licitación formal vinculada a una oportunidad.
 *
 * @module Bidding (MAI-018)
 * @table bidding.tenders
 * @ddl schemas/XX-bidding-schema-ddl.sql
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  OneToMany,
  JoinColumn,
  Index,
} from 'typeorm';
import { Tenant } from '../../core/entities/tenant.entity';
import { User } from '../../core/entities/user.entity';
import { Opportunity } from './opportunity.entity';
import { Proposal } from './proposal.entity';
import { BidCalendar } from './bid-calendar.entity';
import { BidDocument } from './bid-document.entity';

/** Type of tender process */
export type TenderType = 'public' | 'private' | 'invitation_only';

/** Status of the tender */
export type TenderStatus =
  | 'draft'
  | 'published'
  | 'receiving'
  | 'evaluating'
  | 'awarded'
  | 'cancelled'
  | 'converting'
  | 'converted';

@Entity({ schema: 'bidding', name: 'tenders' })
@Index(['tenantId'])
@Index(['tenantId', 'number'], { unique: true })
@Index(['tenantId', 'opportunityId'])
@Index(['tenantId', 'status'])
@Index(['tenantId', 'type'])
@Index(['proposalDeadline'])
export class Tender {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  /** Reference to the opportunity */
  @Column({ name: 'opportunity_id', type: 'uuid' })
  opportunityId: string;

  /** Unique tender number within tenant, format: LIC-2026-001 */
  @Column({ type: 'varchar', length: 50 })
  number: string;

  @Column({
    type: 'varchar',
    length: 30,
    default: 'public',
  })
  type: TenderType;

  @Column({ type: 'varchar', length: 255 })
  title: string;

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

  /** Reference amount (budget) in cents */
  @Column({ name: 'reference_amount', type: 'bigint', nullable: true })
  referenceAmount: string;

  /** Date when the tender was published */
  @Column({ name: 'publication_date', type: 'date', nullable: true })
  publicationDate: Date;

  /** Date for clarification meeting (junta de aclaraciones) */
  @Column({ name: 'clarification_meeting_date', type: 'date', nullable: true })
  clarificationMeetingDate: Date;

  /** Deadline for proposal submission */
  @Column({ name: 'proposal_deadline', type: 'timestamptz' })
  proposalDeadline: Date;

  /** Expected or actual award date */
  @Column({ name: 'award_date', type: 'date', nullable: true })
  awardDate: Date;

  /** Contract duration in days */
  @Column({ name: 'contract_duration_days', type: 'int', nullable: true })
  contractDurationDays: number;

  @Column({
    type: 'varchar',
    length: 30,
    default: 'draft',
  })
  status: TenderStatus;

  /** Reference to the winning proposal */
  @Column({ name: 'winner_id', type: 'uuid', nullable: true })
  winnerId: string;

  // Relations
  @ManyToOne(() => Tenant)
  @JoinColumn({ name: 'tenant_id' })
  tenant: Tenant;

  @ManyToOne(() => Opportunity, (opp) => opp.tenders)
  @JoinColumn({ name: 'opportunity_id' })
  opportunity: Opportunity;

  @ManyToOne(() => Proposal, { nullable: true })
  @JoinColumn({ name: 'winner_id' })
  winner: Proposal;

  @OneToMany(() => Proposal, (proposal) => proposal.tender)
  proposals: Proposal[];

  @OneToMany(() => BidCalendar, (event) => event.tender)
  calendarEvents: BidCalendar[];

  @OneToMany(() => BidDocument, (doc) => doc.tender)
  documents: BidDocument[];

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

  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdById: string;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'created_by' })
  createdBy: User;

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

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

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'updated_by' })
  updatedBy: User;

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