import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  ManyToOne,
  OneToMany,
  JoinColumn,
} from 'typeorm';
import { PurchaseReceipt } from './purchase-receipt.entity';
import { PurchaseMatchingLine } from './purchase-matching-line.entity';
import { MatchingException } from './matching-exception.entity';

export type MatchingStatus =
  | 'pending'
  | 'partial_receipt'
  | 'received'
  | 'partial_invoice'
  | 'matched'
  | 'mismatch';

@Entity({ name: 'purchase_order_matching', schema: 'purchases' })
export class PurchaseOrderMatching {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  @Index()
  @Column({ name: 'purchase_order_id', type: 'uuid' })
  purchaseOrderId: string;

  @Index()
  @Column({ type: 'varchar', length: 20, default: 'pending' })
  status: MatchingStatus;

  @Column({ name: 'total_ordered', type: 'decimal', precision: 15, scale: 2 })
  totalOrdered: number;

  @Column({ name: 'total_received', type: 'decimal', precision: 15, scale: 2, default: 0 })
  totalReceived: number;

  @Column({ name: 'total_invoiced', type: 'decimal', precision: 15, scale: 2, default: 0 })
  totalInvoiced: number;

  // Generated columns (read-only in TypeORM)
  @Column({
    name: 'receipt_variance',
    type: 'decimal',
    precision: 15,
    scale: 2,
    insert: false,
    update: false,
    nullable: true,
  })
  receiptVariance: number;

  @Column({
    name: 'invoice_variance',
    type: 'decimal',
    precision: 15,
    scale: 2,
    insert: false,
    update: false,
    nullable: true,
  })
  invoiceVariance: number;

  @Index()
  @Column({ name: 'last_receipt_id', type: 'uuid', nullable: true })
  lastReceiptId?: string;

  @ManyToOne(() => PurchaseReceipt, { nullable: true })
  @JoinColumn({ name: 'last_receipt_id' })
  lastReceipt?: PurchaseReceipt;

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

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

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

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

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

  // Relations
  @OneToMany(() => PurchaseMatchingLine, (line) => line.matching)
  lines: PurchaseMatchingLine[];

  @OneToMany(() => MatchingException, (exception) => exception.matching)
  exceptions: MatchingException[];
}
