/**
 * APPayment Entity - Pagos a Proveedores
 *
 * Registro de pagos realizados a cuentas por pagar.
 *
 * @module Finance
 */

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

export type PaymentMethod = 'cash' | 'check' | 'transfer' | 'card' | 'compensation' | 'other';
export type PaymentStatus = 'pending' | 'processed' | 'reconciled' | 'cancelled' | 'returned';

@Entity('ap_payments', { schema: 'finance' })
@Index(['tenantId', 'accountPayableId'])
@Index(['tenantId', 'paymentDate'])
@Index(['tenantId', 'bankAccountId'])
export class APPayment {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

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

  // Número de pago
  @Column({ name: 'payment_number', length: 50 })
  paymentNumber!: string;

  // Cuenta por pagar asociada
  @Column({ name: 'account_payable_id', type: 'uuid' })
  accountPayableId!: string;

  @ManyToOne(() => AccountPayable, (ap) => ap.payments)
  @JoinColumn({ name: 'account_payable_id' })
  accountPayable?: AccountPayable;

  // Método de pago
  @Column({
    name: 'payment_method',
    type: 'enum',
    enum: ['cash', 'check', 'transfer', 'card', 'compensation', 'other'],
    enumName: 'payment_method',
  })
  paymentMethod!: PaymentMethod;

  @Column({
    type: 'enum',
    enum: ['pending', 'processed', 'reconciled', 'cancelled', 'returned'],
    enumName: 'payment_status',
    default: 'pending',
  })
  status!: PaymentStatus;

  // Fecha de pago
  @Column({ name: 'payment_date', type: 'date' })
  paymentDate!: 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 origen
  @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 pago
  @Column({ name: 'check_number', length: 50, nullable: true })
  checkNumber?: string;

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

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

  // Beneficiario
  @Column({ name: 'beneficiary_name', length: 255, nullable: true })
  beneficiaryName?: string;

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

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

  @Column({ name: 'beneficiary_clabe', length: 18, nullable: true })
  beneficiaryClabe?: 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;
}
