/**
 * BankReconciliation Entity - Conciliaciones Bancarias
 *
 * Registro de procesos de conciliación bancaria.
 *
 * @module Finance
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  JoinColumn,
  Index,
} from 'typeorm';
import { User } from '../../core/entities/user.entity';
import { BankAccount } from './bank-account.entity';

export type ReconciliationStatus = 'draft' | 'in_progress' | 'completed' | 'approved' | 'cancelled';

@Entity('bank_reconciliations', { schema: 'finance' })
@Index(['tenantId', 'bankAccountId'])
@Index(['tenantId', 'periodEnd'])
@Index(['tenantId', 'status'])
export class BankReconciliation {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

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

  // Cuenta bancaria
  @Column({ name: 'bank_account_id', type: 'uuid' })
  bankAccountId!: string;

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

  // Periodo de conciliación
  @Column({ name: 'period_start', type: 'date' })
  periodStart!: Date;

  @Column({ name: 'period_end', type: 'date' })
  periodEnd!: Date;

  // Estado
  @Column({
    type: 'enum',
    enum: ['draft', 'in_progress', 'completed', 'approved', 'cancelled'],
    enumName: 'reconciliation_status',
    default: 'draft',
  })
  status!: ReconciliationStatus;

  // Saldos según banco
  @Column({
    name: 'bank_opening_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  bankOpeningBalance!: number;

  @Column({
    name: 'bank_closing_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  bankClosingBalance!: number;

  // Saldos según libros
  @Column({
    name: 'book_opening_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  bookOpeningBalance!: number;

  @Column({
    name: 'book_closing_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  bookClosingBalance!: number;

  // Partidas de conciliación
  @Column({
    name: 'deposits_in_transit',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  depositsInTransit!: number;

  @Column({
    name: 'checks_in_transit',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  checksInTransit!: number;

  @Column({
    name: 'bank_charges_not_recorded',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  bankChargesNotRecorded!: number;

  @Column({
    name: 'interest_not_recorded',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  interestNotRecorded!: number;

  @Column({
    name: 'other_adjustments',
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  otherAdjustments!: number;

  // Saldo conciliado
  @Column({
    name: 'reconciled_balance',
    type: 'decimal',
    precision: 18,
    scale: 2,
  })
  reconciledBalance!: number;

  // Diferencia (debe ser 0 si está conciliado)
  @Column({
    type: 'decimal',
    precision: 18,
    scale: 2,
    default: 0,
  })
  difference!: number;

  @Column({ name: 'is_balanced', type: 'boolean', default: false })
  isBalanced!: boolean;

  // Contadores
  @Column({ name: 'total_movements', type: 'int', default: 0 })
  totalMovements!: number;

  @Column({ name: 'reconciled_movements', type: 'int', default: 0 })
  reconciledMovements!: number;

  @Column({ name: 'pending_movements', type: 'int', default: 0 })
  pendingMovements!: number;

  // Estado de cuenta bancario (archivo importado)
  @Column({ name: 'statement_file_path', length: 500, nullable: true })
  statementFilePath?: string;

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

  // Fechas de proceso
  @Column({ name: 'started_at', type: 'timestamptz', nullable: true })
  startedAt?: Date;

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

  // Aprobación
  @Column({ name: 'approved_by_id', type: 'uuid', nullable: true })
  approvedById?: string;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'approved_by_id' })
  approvedBy?: User;

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

  // Póliza de ajuste generada
  @Column({ name: 'adjustment_entry_id', type: 'uuid', nullable: true })
  adjustmentEntryId?: string;

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

  @Column({ name: 'reconciliation_items', type: 'jsonb', nullable: true })
  reconciliationItems?: Record<string, any>[];

  @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;
}
