import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { TransactionEntity } from '../../domain/entities/transaction.entity';
import {
  Column,
  Entity,
  JoinColumn,
  ManyToOne,
  OneToMany,
  OneToOne,
} from 'typeorm';
import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model';
import {
  TransactionType,
  TransactionUserType,
  TransactionPaymentType,
} from '../../constants';
import { TransactionItemModel } from './transaction-item.model';
import { TransactionTaxModel } from './transaction-tax.model';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { RefundModel } from 'src/modules/transaction/refund/data/models/refund.model';
import { TransactionDemographyModel } from './transaction-demography.model';
import { VipCategoryModel } from 'src/modules/transaction/vip-category/data/models/vip-category.model';

@Entity(TABLE_NAME.TRANSACTION)
export class TransactionModel
  extends BaseStatusModel<TransactionEntity>
  implements TransactionEntity
{
  // general info
  @Column('bool', { name: 'is_recap_transaction', default: false })
  is_recap_transaction: boolean;

  @Column('enum', {
    name: 'type',
    enum: TransactionType,
    default: TransactionType.ADMIN,
  })
  type: TransactionType;

  @Column('varchar', { name: 'invoice_code', nullable: true })
  invoice_code: string;

  @Column('int', { name: 'creator_counter_no', nullable: true })
  creator_counter_no: number;

  @Column('varchar', { name: 'creator_counter_name', nullable: true })
  creator_counter_name: string;

  // season data
  @Column('varchar', { name: 'season_period_id', nullable: true })
  season_period_id: string;

  @Column('varchar', { name: 'season_period_name', nullable: true })
  season_period_name: string;

  @Column('varchar', { name: 'season_period_type_id', nullable: true })
  season_period_type_id: string;

  @Column('varchar', { name: 'season_period_type_name', nullable: true })
  season_period_type_name: string;

  @ManyToOne(() => VipCategoryModel)
  @JoinColumn({ name: 'customer_category_id' })
  customer_category: VipCategoryModel;

  // customer info
  @Column('enum', {
    name: 'customer_type',
    enum: TransactionUserType,
    nullable: true,
  })
  customer_type: TransactionUserType;

  @Column('varchar', { name: 'customer_category_id', nullable: true })
  customer_category_id: string;

  @Column('varchar', { name: 'customer_category_name', nullable: true })
  customer_category_name: string;

  @Column('varchar', { name: 'customer_name', nullable: true })
  customer_name: string;

  @Column('varchar', { name: 'customer_phone', nullable: true })
  customer_phone: string;

  @Column('varchar', { name: 'customer_email', nullable: true })
  customer_email: string;

  @Column('varchar', { name: 'customer_description', nullable: true })
  customer_description: string;

  @Column('varchar', { name: 'no_of_group', nullable: true })
  no_of_group: number;

  @Column('date', { name: 'booking_date', nullable: true })
  booking_date: Date;

  @Column('date', { name: 'booking_date_before', nullable: true })
  booking_date_before: Date;

  @Column('date', { name: 'settlement_date', nullable: true })
  settlement_date: Date;

  @Column('date', { name: 'invoice_date', nullable: true })
  invoice_date: Date;

  // discount data
  @Column('varchar', { name: 'discount_code_id', nullable: true })
  discount_code_id: string;

  @Column('varchar', { name: 'discount_code', nullable: true })
  discount_code: string;

  @Column('decimal', { name: 'discount_percentage', nullable: true })
  discount_percentage: number;

  @Column('decimal', { name: 'discount_value', nullable: true })
  discount_value: number;

  // payment data
  @Column('enum', {
    name: 'payment_type',
    enum: TransactionPaymentType,
    default: TransactionPaymentType.BANK_TRANSFER,
  })
  payment_type: TransactionPaymentType;

  @Column('enum', {
    name: 'payment_type_counter',
    enum: TransactionPaymentType,
    nullable: true,
  })
  payment_type_counter: TransactionPaymentType;

  @Column('varchar', { name: 'payment_code', nullable: true })
  payment_code: string;

  @Column('varchar', { name: 'payment_type_method_id', nullable: true })
  payment_type_method_id: string;

  @Column('varchar', { name: 'payment_type_method_name', nullable: true })
  payment_type_method_name: string;

  @Column('varchar', { name: 'payment_type_method_number', nullable: true })
  payment_type_method_number: string;

  @Column('varchar', { name: 'payment_type_method_qr', nullable: true })
  payment_type_method_qr: string;

  @Column('varchar', { name: 'payment_card_information', nullable: true })
  payment_card_information: string;

  @Column('varchar', { name: 'payment_code_reference', nullable: true })
  payment_code_reference: string;

  @Column('varchar', { name: 'payment_midtrans_token', nullable: true })
  payment_midtrans_token: string;

  @Column('varchar', { name: 'payment_midtrans_url', nullable: true })
  payment_midtrans_url: string;

  @Column('date', { name: 'payment_date', nullable: true })
  payment_date: Date;

  @Column('date', { name: 'payment_date_bank', nullable: true })
  payment_date_bank: Date;

  // calculation data
  @Column('decimal', { name: 'payment_sub_total', nullable: true })
  payment_sub_total: number;

  @Column('decimal', { name: 'payment_discount_total', nullable: true })
  payment_discount_total: number;

  @Column('decimal', { name: 'payment_total', nullable: true })
  payment_total: number;

  @Column('decimal', { name: 'payment_total_pay', nullable: true })
  payment_total_pay: number;

  @Column('decimal', { name: 'payment_change', nullable: true })
  payment_change: number;

  // share and profit data
  @Column('decimal', { name: 'payment_total_dpp', nullable: true })
  payment_total_dpp: number;

  @Column('decimal', { name: 'payment_total_share', nullable: true })
  payment_total_share: number;

  @Column('decimal', { name: 'payment_total_tax', nullable: true })
  payment_total_tax: number;

  @Column('decimal', { name: 'payment_total_profit', nullable: true })
  payment_total_profit: number;

  @Column('varchar', { name: 'profit_share_formula', nullable: true })
  profit_share_formula: string;

  @Column('varchar', { name: 'sales_price_formula', nullable: true })
  sales_price_formula: string;

  // mdr
  @Column('decimal', { name: 'reconciliation_mdr', nullable: true })
  reconciliation_mdr: number;

  @Column('enum', {
    name: 'reconciliation_status',
    enum: STATUS,
    default: STATUS.DRAFT,
  })
  reconciliation_status: STATUS;

  @Column('varchar', { name: 'reconciliation_confirm_date', nullable: true })
  reconciliation_confirm_date: string;

  @Column('varchar', { name: 'reconciliation_confirm_by', nullable: true })
  reconciliation_confirm_by: string;

  @Column('decimal', { name: 'payment_total_net_profit', nullable: true })
  payment_total_net_profit: number;

  // sending data
  @Column('enum', {
    name: 'sending_invoice_status',
    enum: STATUS,
    nullable: true,
  })
  sending_invoice_status: STATUS;

  @Column({ name: 'sending_invoice_at', type: 'bigint', nullable: true })
  sending_invoice_at: number;

  @Column('enum', { name: 'sending_qr_status', enum: STATUS, nullable: true })
  sending_qr_status: STATUS;

  @Column({ name: 'sending_qr_at', type: 'bigint', nullable: true })
  sending_qr_at: number;

  // calendar
  @Column('varchar', { name: 'calendar_id', nullable: true })
  calendar_id: string;

  @Column('varchar', { name: 'calendar_link', nullable: true })
  calendar_link: string;

  // relations to item
  @OneToMany(() => TransactionItemModel, (model) => model.transaction, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  items: TransactionItemModel[];

  // relations to tax data
  @OneToMany(() => TransactionTaxModel, (model) => model.transaction, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  taxes: TransactionTaxModel[];

  @OneToOne(() => TransactionDemographyModel, (model) => model.transaction, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  demographies: TransactionDemographyModel;

  // relations to refund
  @OneToMany(() => RefundModel, (model) => model.transaction, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  refunds: RefundModel[];

  @Column('varchar', { name: 'parent_id', nullable: true })
  parent_id: string;

  @ManyToOne(() => TransactionModel, (model) => model.id, {
    nullable: true,
  })
  @JoinColumn({ name: 'parent_id' })
  parent_transaction: TransactionModel;

  @OneToMany(() => TransactionModel, (model) => model.parent_transaction, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  children_transactions: TransactionModel[];

  @Column('varchar', { name: 'otp_code', nullable: true })
  otp_code: string;
}
