import { Entity, Column, Index, Check, ManyToOne, JoinColumn } from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { BankAccountEntity } from './bank-account.entity';
import { BookingCashCollectionEntity } from './booking-cash-collection.entity';
import { CurrencyEntity } from './currency.entity';
import { CollectionPartyType } from './payment-collection.entity';
import { SettlementPaymentMode } from './settlement-payment.entity';

export type MdCashBatchStatus = 'PENDING' | 'POSTED';

export interface MdCashBatchAllocation {
  settlement_id: string;
  amount: number;
}

/**
 * One Collect-for-MD submit. Posted on MD "Confirm collected".
 */
@Entity('booking_cash_collection_batches')
@Index('ix_bcc_batch_parent', ['tenant_id', 'booking_cash_collection_id'], {
  where: '"is_deleted" = false',
})
@Check('chk_bcc_batch_status', `"status" IN ('PENDING','POSTED')`)
@Check('chk_bcc_batch_party', `"party_type" IN ('CUSTOMER','SOURCE')`)
@Check('chk_bcc_batch_received', `"received_amount" > 0`)
@Check('chk_bcc_batch_roe_non_neg', `"roe" IS NULL OR "roe" >= 0`)
export class BookingCashCollectionBatchEntity extends BaseEntity {
  @ManyToOne(() => BookingCashCollectionEntity, (c) => c.batches, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'booking_cash_collection_id' })
  collection: BookingCashCollectionEntity;

  @Column({ type: 'uuid' })
  booking_cash_collection_id: string;

  @Column({ type: 'decimal', precision: 12, scale: 2 })
  received_amount: number;

  @Column({ type: 'decimal', precision: 12, scale: 6, nullable: true })
  roe: number | null;

  @ManyToOne(() => CurrencyEntity, { nullable: true })
  @JoinColumn({ name: 'receive_currency_id' })
  receive_currency: CurrencyEntity | null;

  @Column({ type: 'uuid', nullable: true })
  receive_currency_id: string | null;

  @Column({ type: 'decimal', precision: 12, scale: 6, nullable: true })
  exchange_rate: number | null;

  /** Rate as entered in the natural "1 Bill = X Receive" direction,
   *  kept verbatim for display. See migration 1787700000000. */
  @Column({ type: 'decimal', precision: 18, scale: 6, nullable: true })
  exchange_rate_quote: number | null;

  @Column({ type: 'decimal', precision: 12, scale: 2, nullable: true })
  received_amount_receive_currency: number | null;

  @ManyToOne(() => CurrencyEntity)
  @JoinColumn({ name: 'currency_id' })
  currency: CurrencyEntity;

  @Column({ type: 'uuid' })
  currency_id: string;

  @Column({ type: 'varchar', length: 16 })
  party_type: CollectionPartyType;

  @Column({ type: 'varchar', length: 20, nullable: true })
  customer_mobile: string | null;

  @Column({ type: 'uuid', nullable: true })
  source_id: string | null;

  @Column({ type: 'varchar', length: 200, nullable: true })
  customer_name: string | null;

  @Column({ type: 'date' })
  payment_date: string;

  @Column({ type: 'varchar', length: 32 })
  mode: SettlementPaymentMode;

  @ManyToOne(() => BankAccountEntity, { nullable: true })
  @JoinColumn({ name: 'debit_bank_account_id' })
  debit_bank_account: BankAccountEntity | null;

  @Column({ type: 'uuid', nullable: true })
  debit_bank_account_id: string | null;

  @ManyToOne(() => BankAccountEntity, { nullable: true })
  @JoinColumn({ name: 'credit_bank_account_id' })
  credit_bank_account: BankAccountEntity | null;

  @Column({ type: 'uuid', nullable: true })
  credit_bank_account_id: string | null;

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

  @Column({ type: 'jsonb' })
  allocations: MdCashBatchAllocation[];

  @Column({ type: 'varchar', length: 20, default: 'PENDING' })
  status: MdCashBatchStatus;

  /** Receipt created when this batch is posted on MD confirm. */
  @Column({ type: 'uuid', nullable: true })
  payment_collection_id: string | null;
}
