import { Entity, Column, Index, ManyToOne, JoinColumn, OneToMany } from 'typeorm';
import { BaseEntity } from '../database/base.entity';
import { CurrencyEntity } from './currency.entity';
import { PaymentCollectionEntity } from './payment-collection.entity';
import { CustomerCreditLedgerMovementEntity } from './customer-credit-ledger-movement.entity';

/**
 * Phase D §12d — Customer / Agent credit ledger header.
 *
 * One row per (party_type, party_key, currency_id). Balance is the
 * running excess-credit on file, mutated only by ledger movements so
 * the movements log answers "where did this 1,250 AED come from /
 * go to" for any audit question.
 *
 * party_type:
 *   - CUSTOMER → party_key = the guest's mobile reduced to digits only
 *     (see `normaliseMobileForLedger`). Phase 1 has no Customer Master;
 *     mobile beats name because two guests can share a name.
 *   - SOURCE   → party_key = trip_source uuid (stringified). The
 *     "agent" wiring money on behalf of customers; the external
 *     channel that brought the booking.
 *   - SUPPLIER → party_key = supplier uuid. Balance is money the
 *     supplier holds for us after an over-payment / deposit, drawn
 *     down on the next Pay Supplier voucher (§12e prepayment).
 *
 * party_label is the display name snapshotted at write-time so the UI
 * can show "Naveen Kumar" while the lookup key stays "919876543210".
 */
export enum CreditLedgerPartyType {
  CUSTOMER = 'CUSTOMER',
  SOURCE = 'SOURCE',
  SUPPLIER = 'SUPPLIER',
}

@Entity('customer_credit_ledger')
@Index(['tenant_id', 'party_type', 'party_key', 'currency_id'], { unique: true })
@Index(['tenant_id', 'party_type', 'party_key'])
export class CustomerCreditLedgerEntity extends BaseEntity {
  @Column({ type: 'varchar', length: 16 })
  party_type: CreditLedgerPartyType;

  @Column({ type: 'varchar', length: 200 })
  party_key: string;

  @Column({ type: 'varchar', length: 200 })
  party_label: string;

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

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

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

  @ManyToOne(() => PaymentCollectionEntity, { nullable: true })
  @JoinColumn({ name: 'last_collection_id' })
  last_collection: PaymentCollectionEntity | null;

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

  /** Supplier-side mirror of `last_collection_id` — the payout that
   *  last moved this balance. Null on customer / agent ledgers. */
  @Column({ type: 'uuid', nullable: true })
  last_payout_id: string | null;

  @OneToMany(() => CustomerCreditLedgerMovementEntity, (m) => m.ledger)
  movements: CustomerCreditLedgerMovementEntity[];
}
