/**
 * Contract Entity
 * Contratos con clientes y subcontratistas
 *
 * @module Contracts
 * @table contracts.contracts
 */

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 { ContractAddendum } from './contract-addendum.entity';

export type ContractType = 'client' | 'subcontractor';
export type ContractStatus = 'draft' | 'review' | 'approved' | 'active' | 'completed' | 'terminated';
export type ClientContractType = 'desarrollo' | 'llave_en_mano' | 'administracion';

@Entity({ schema: 'construction', name: 'contratos' })
@Index(['tenantId', 'contractNumber'], { unique: true })
export class Contract {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

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

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

  @Column({ name: 'contract_number', type: 'varchar', length: 50 })
  contractNumber: string;

  @Column({ name: 'contract_type', type: 'varchar', length: 20 })
  contractType: ContractType;

  @Column({ name: 'client_contract_type', type: 'varchar', length: 30, nullable: true })
  clientContractType: ClientContractType;

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

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

  // Client info (for client contracts)
  @Column({ name: 'client_name', type: 'varchar', length: 255, nullable: true })
  clientName: string;

  @Column({ name: 'client_rfc', type: 'varchar', length: 13, nullable: true })
  clientRfc: string;

  @Column({ name: 'client_address', type: 'text', nullable: true })
  clientAddress: string;

  // Subcontractor info (for subcontractor contracts)
  @Column({ name: 'subcontractor_id', type: 'uuid', nullable: true })
  subcontractorId: string;

  @Column({ name: 'specialty', type: 'varchar', length: 50, nullable: true })
  specialty: string;

  // Contract terms
  @Column({ name: 'start_date', type: 'date' })
  startDate: Date;

  @Column({ name: 'end_date', type: 'date' })
  endDate: Date;

  @Column({ name: 'contract_amount', type: 'decimal', precision: 16, scale: 2 })
  contractAmount: number;

  @Column({ type: 'varchar', length: 3, default: 'MXN' })
  currency: string;

  @Column({ name: 'payment_terms', type: 'text', nullable: true })
  paymentTerms: string;

  @Column({ name: 'retention_percentage', type: 'decimal', precision: 5, scale: 2, default: 5 })
  retentionPercentage: number;

  @Column({ name: 'advance_percentage', type: 'decimal', precision: 5, scale: 2, default: 0 })
  advancePercentage: number;

  // Status and workflow
  @Column({ type: 'varchar', length: 20, default: 'draft' })
  status: ContractStatus;

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

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

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

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

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

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

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

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

  @Column({ name: 'termination_reason', type: 'text', nullable: true })
  terminationReason: string;

  // Documents
  @Column({ name: 'document_url', type: 'varchar', length: 500, nullable: true })
  documentUrl: string;

  @Column({ name: 'signed_document_url', type: 'varchar', length: 500, nullable: true })
  signedDocumentUrl: string;

  // Progress tracking
  @Column({ name: 'progress_percentage', type: 'decimal', precision: 5, scale: 2, default: 0 })
  progressPercentage: number;

  @Column({ name: 'invoiced_amount', type: 'decimal', precision: 16, scale: 2, default: 0 })
  invoicedAmount: number;

  @Column({ name: 'paid_amount', type: 'decimal', precision: 16, scale: 2, default: 0 })
  paidAmount: number;

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

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

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

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

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

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

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

  // Computed properties
  get remainingAmount(): number {
    return Number(this.contractAmount) - Number(this.invoicedAmount);
  }

  get isExpiring(): boolean {
    const thirtyDaysFromNow = new Date();
    thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);
    return this.endDate <= thirtyDaysFromNow && this.status === 'active';
  }

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

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

  @ManyToOne(() => User)
  @JoinColumn({ name: 'approved_by' })
  approvedBy: User;

  @OneToMany(() => ContractAddendum, (a) => a.contract)
  addendums: ContractAddendum[];
}
