/**
 * ARPayment Entity - Cobros de Clientes
 *
 * Registro de cobros recibidos de cuentas por cobrar.
 *
 * @module Finance
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  JoinColumn,
  Index,
} from 'typeorm';
import { AccountReceivable } from './account-receivable.entity';
import { BankAccount } from './bank-account.entity';

export type CollectionMethod = 'cash' | 'check' | 'transfer' | 'card' | 'compensation' | 'other';
export type CollectionStatus = 'pending' | 'deposited' | 'reconciled' | 'cancelled' | 'returned';

@Entity('ar_payments', { schema: 'finance' })
@Index(['tenantId', 'accountReceivableId'])
@Index(['tenantId', 'collectionDate'])
@Index(['tenantId', 'bankAccountId'])
export class ARPayment {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

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

  // Número de cobro
  @Column({ name: 'collection_number', length: 50 })
  collectionNumber!: string;

  // Cuenta por cobrar asociada
  @Column({ name: 'account_receivable_id', type: 'uuid' })
  accountReceivableId!: string;

  @ManyToOne(() => AccountReceivable, (ar) => ar.payments)
  @JoinColumn({ name: 'account_receivable_id' })
  accountReceivable?: AccountReceivable;

  // Método de cobro
  @Column({
    name: 'collection_method',
    type: 'enum',
    enum: ['cash', 'check', 'transfer', 'card', 'compensation', 'other'],
    enumName: 'collection_method',
  })
  collectionMethod!: CollectionMethod;

  @Column({
    type: 'enum',
    enum: ['pending', 'deposited', 'reconciled', 'cancelled', 'returned'],
    enumName: 'collection_status',
    default: 'pending',
  })
  status!: CollectionStatus;

  // Fecha de cobro
  @Column({ name: 'collection_date', type: 'date' })
  collectionDate!: Date;

  @Column({ name: 'deposit_date', type: 'date', nullable: true })
  depositDate?: Date;

  // Monto
  @Column({
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  amount!: number;

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

  @Column({
    name: 'exchange_rate',
    type: 'decimal',
    precision: 12,
    scale: 6,
    default: 1,
  })
  exchangeRate!: number;

  // Cuenta bancaria de destino
  @Column({ name: 'bank_account_id', type: 'uuid', nullable: true })
  bankAccountId?: string;

  @ManyToOne(() => BankAccount, { nullable: true })
  @JoinColumn({ name: 'bank_account_id' })
  bankAccount?: BankAccount;

  // Detalles del instrumento de cobro
  @Column({ name: 'check_number', length: 50, nullable: true })
  checkNumber?: string;

  @Column({ name: 'check_bank', length: 100, nullable: true })
  checkBank?: string;

  @Column({ name: 'transfer_reference', length: 100, nullable: true })
  transferReference?: string;

  // Pagador (si es diferente al cliente)
  @Column({ name: 'payer_name', length: 255, nullable: true })
  payerName?: string;

  @Column({ name: 'payer_bank', length: 100, nullable: true })
  payerBank?: string;

  @Column({ name: 'payer_account', length: 50, nullable: true })
  payerAccount?: string;

  // Póliza contable generada
  @Column({ name: 'accounting_entry_id', type: 'uuid', nullable: true })
  accountingEntryId?: string;

  // Conciliación bancaria
  @Column({ name: 'bank_movement_id', type: 'uuid', nullable: true })
  bankMovementId?: string;

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

  // Notas y metadatos
  @Column({ type: 'text', nullable: true })
  notes?: string;

  @Column({ type: 'jsonb', nullable: true })
  metadata?: Record<string, any>;

  // Auditoría
  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy?: string;

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

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

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

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