import {
  Column,
  CreateDateColumn,
  DeleteDateColumn,
  Entity,
  Index,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';
import { Member } from './member.entity';
import { Office } from './office.entity';
import { Application } from './application.entity';
import { LoanPayment } from './loan-payment.entity';

@Entity({ name: 'loan_accounts' })
@Index('idx_loans_status_type', ['status', 'loanType'])
export class LoanAccount {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  /** Auto-generated: LON-00001 */
  @Index()
  @Column({ type: 'varchar', name: 'loan_number', length: 30, nullable: true })
  loanNumber?: string;

  // ── Links ──────────────────────────────────────────────────────────────────
  @Column({ type: 'varchar', name: 'application_id', nullable: true })
  applicationId?: string;

  @ManyToOne(() => Application, { nullable: true, onDelete: 'SET NULL' })
  application?: Application;

  @Index()
  @Column({ type: 'varchar', name: 'member_id', nullable: true })
  memberId?: string;

  @ManyToOne(() => Member, { nullable: true, onDelete: 'SET NULL' })
  member?: Member;

  @Column({ type: 'varchar', name: 'office_id', nullable: true })
  officeId?: string;

  @ManyToOne(() => Office, { nullable: true, onDelete: 'SET NULL' })
  office?: Office;

  // ── Loan Classification ────────────────────────────────────────────────────
  /** e.g. home_loan, personal_loan, business_loan, micro_credit, hire_purchase */
  @Column({ type: 'varchar', name: 'loan_type', length: 50, nullable: true })
  loanType?: string;

  /** Lookup: loan_purpose */
  @Column({ type: 'varchar', name: 'loan_purpose', length: 100, nullable: true })
  loanPurpose?: string;

  /** Lookup: loan_title */
  @Column({ type: 'varchar', name: 'loan_title', length: 100, nullable: true })
  loanTitle?: string;

  // ── Amounts ───────────────────────────────────────────────────────────────
  @Column({ name: 'sanctioned_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  sanctionedAmount?: number;

  @Column({ name: 'disbursed_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  disbursedAmount?: number;

  /** Remaining principal balance */
  @Column({ name: 'outstanding_balance', type: 'decimal', precision: 15, scale: 2, default: 0 })
  outstandingBalance!: number;

  /** Total interest paid to date */
  @Column({ name: 'total_interest_paid', type: 'decimal', precision: 15, scale: 2, default: 0 })
  totalInterestPaid!: number;

  /** Total principal paid to date */
  @Column({ name: 'total_principal_paid', type: 'decimal', precision: 15, scale: 2, default: 0 })
  totalPrincipalPaid!: number;

  /** Accrued penalty (overdue fees) */
  @Column({ name: 'penalty_balance', type: 'decimal', precision: 15, scale: 2, default: 0 })
  penaltyBalance!: number;

  // ── Terms ─────────────────────────────────────────────────────────────────
  @Column({ name: 'interest_rate', type: 'decimal', precision: 5, scale: 2, default: 0 })
  interestRate!: number;

  /** Term in months */
  @Column({ name: 'term_months', nullable: true })
  termMonths?: number;

  /** monthly | quarterly | semi_annual | annual | bullet */
  @Column({ type: 'varchar', name: 'repayment_type', length: 30, nullable: true })
  repaymentType?: string;

  /** Calculated EMI amount */
  @Column({ name: 'emi_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  emiAmount?: number;

  // ── Dates ─────────────────────────────────────────────────────────────────
  @Column({ type: 'varchar', name: 'disbursement_date', length: 20, nullable: true })
  disbursementDate?: string;

  @Column({ type: 'varchar', name: 'disbursement_date_bs', length: 20, nullable: true })
  disbursementDateBs?: string;

  @Column({ type: 'varchar', name: 'maturity_date', length: 20, nullable: true })
  maturityDate?: string;

  @Column({ type: 'varchar', name: 'maturity_date_bs', length: 20, nullable: true })
  maturityDateBs?: string;

  @Column({ type: 'varchar', name: 'last_payment_date', length: 20, nullable: true })
  lastPaymentDate?: string;

  @Column({ type: 'varchar', name: 'last_payment_date_bs', length: 20, nullable: true })
  lastPaymentDateBs?: string;

  @Column({ type: 'varchar', name: 'close_date', length: 20, nullable: true })
  closeDate?: string;

  @Column({ type: 'varchar', name: 'close_date_bs', length: 20, nullable: true })
  closeDateBs?: string;

  // ── Collateral ────────────────────────────────────────────────────────────
  /** home | land | vehicle | fixed_deposit | salary | guarantee | other */
  @Column({ type: 'varchar', name: 'collateral_type', length: 50, nullable: true })
  collateralType?: string;

  @Column({ name: 'collateral_description', type: 'text', nullable: true })
  collateralDescription?: string;

  @Column({ name: 'collateral_value', type: 'decimal', precision: 15, scale: 2, nullable: true })
  collateralValue?: number;

  @Column({ type: 'varchar', name: 'collateral_owner_name', length: 100, nullable: true })
  collateralOwnerName?: string;

  @Column({ type: 'varchar', name: 'collateral_owner_relation', length: 50, nullable: true })
  collateralOwnerRelation?: string;

  // ── Insurance ─────────────────────────────────────────────────────────────
  @Column({ type: 'varchar', name: 'insurance_company', length: 100, nullable: true })
  insuranceCompany?: string;

  @Column({ type: 'varchar', name: 'insurance_policy_no', length: 50, nullable: true })
  insurancePolicyNo?: string;

  @Column({ type: 'varchar', name: 'insurance_expiry_bs', length: 20, nullable: true })
  insuranceExpiryBs?: string;

  // ── Status ────────────────────────────────────────────────────────────────
  /** active | closed | NPL | written_off | restructured */
  @Index()
  @Column({ type: 'varchar', length: 30, default: 'active' })
  status!: string;

  @Column({ type: 'varchar', name: 'npl_date', length: 20, nullable: true })
  nplDate?: string;

  @Column({ name: 'overdue_days', default: 0 })
  overdueDays!: number;

  // ── Meta ──────────────────────────────────────────────────────────────────
  @Column({ type: 'varchar', name: 'fiscal_year', length: 20, nullable: true })
  fiscalYear?: string;

  @Column({ type: 'text', nullable: true })
  remarks?: string;

  @Column({ type: 'varchar', name: 'created_by', nullable: true })
  createdBy?: string;

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

  // ── Relations ─────────────────────────────────────────────────────────────
  @OneToMany(() => LoanPayment, (p) => p.loanAccount, { cascade: false })
  payments?: LoanPayment[];

  // ── Timestamps ────────────────────────────────────────────────────────────
  @CreateDateColumn({ name: 'created_at' })
  createdAt!: Date;

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

  @DeleteDateColumn({ name: 'deleted_at' })
  deletedAt?: Date;
}
