import {
  BaseEntity,
  Column,
  Entity,
  Index,
  JoinColumn,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
} from 'typeorm';
import { DrivingOffenseEntity } from '../../drivinig-offense/entities/driving-offense.entity';
import { NegativeScoreEntity } from '../../negative-score/entities/negative-score.entity';
import { UserEntity } from '../../user/entities/user.entity';
import { OrderEntity } from '../../order/entities/order.entity';
import { FreewayTollEntity } from '../../freeway-toll/entities/freeway-toll.entity';
import { DrivingOffenseBillEntity } from '../../drivinig-offense/entities/driving-offense-bill.entity';

export enum PaymentStatus {
  pending = 'pending',
  done = 'done',
  rejected = 'rejected',
}

export enum PaymentType {
  shop = 'shop',
  service = 'service',
  oil_gov_service = 'oil_gov_service',
  oil_gov_shop = 'oil_gov_shop',
  freeway_inquiry = 'freeway_inquiry',
  offense_inquiry = 'offense_inquiry',
  negative_inquiry = 'negative_inquiry',
  offense_pay = 'offense_pay',
}

export enum PaymentGateway {
  meli = 'meli',
  zarinpal = 'zarinpal',
  kimia = 'kimia',
  tara = 'tara',
  snappPay = 'snapp_pay',
}

export enum PaymentGatewayCode {
  meli = 1,
  zarinpal = 2,
  kimia = 3,
  tara = 4,
  snapp_pay = 5,
}

@Index('fk_payments_users1_idx', ['userId'], {})
@Index('orderId', ['orderId'], {})
@Entity('payments')
export class PaymentEntity extends BaseEntity {
  @PrimaryGeneratedColumn({ type: 'int', name: 'id' })
  id: number;

  @Column('varchar', {
    name: 'businessPartnerCode',
    nullable: true,
    length: 45,
  })
  businessPartnerCode: string | null;

  @Column('char', { name: 'userId', nullable: true, length: 36 })
  userId: string | null;

  @Column('varchar', { name: 'result', nullable: true, length: 255 })
  result: string | null;

  @Column('int', { name: 'orderId', nullable: true })
  orderId: number | null;

  @Column('varchar', { name: 'orderDate', nullable: true, length: 255 })
  orderDate: string | null;

  @Column('varchar', { name: 'cardNumber', nullable: true, length: 255 })
  cardNumber: string | null;

  @Column('varchar', { name: 'referenceId', nullable: true, length: 255 })
  referenceId: string | null;

  @Column('varchar', { name: 'referenceNumber', nullable: true, length: 255 })
  referenceNumber: string | null;

  @Column('varchar', { name: 'tranceNumber', nullable: true, length: 255 })
  tranceNumber: string | null;

  @Column('varchar', { name: 'transactionDate', nullable: true, length: 10 })
  transactionDate: string | null;

  @Column('varchar', { name: 'authority', nullable: true, length: 128 })
  authority: string | null;

  @Column('int', { name: 'amount', nullable: true })
  amount: number | null;

  @Column('int', { name: 'usedWalletAmount', nullable: true })
  usedWalletAmount: number | null;

  @Column('int', { name: 'gateway', nullable: true })
  gateway: PaymentGatewayCode | null;

  @Column('enum', {
    name: 'status',
    enum: PaymentStatus,
    default: () => PaymentStatus.done,
  })
  status: PaymentStatus;

  @Column('enum', {
    name: 'type',
    nullable: true,
    enum: PaymentType,
  })
  type: PaymentType | null;

  @Column('int', { name: 'clientType', default: () => "'1'" })
  clientType: number;

  @Column('text', { name: 'taraToken', nullable: true })
  taraToken: string | null;

  @Column('datetime', { name: 'createdAt' })
  createdAt: Date;

  @Column('datetime', { name: 'updatedAt' })
  updatedAt: Date;

  /**
   * Relations
   */
  @OneToMany(
    () => DrivingOffenseBillEntity,
    (drivingOffenseBills) => drivingOffenseBills.payment,
  )
  drivingOffenseBills: DrivingOffenseBillEntity[];

  @OneToMany(
    () => DrivingOffenseEntity,
    (drivingOffenses) => drivingOffenses.paymentInquiry,
  )
  drivingOffenses: DrivingOffenseEntity[];

  @OneToMany(
    () => NegativeScoreEntity,
    (negativeScores) => negativeScores.paymentInquiry,
  )
  negativeScores: NegativeScoreEntity[];

  @OneToMany(
    () => FreewayTollEntity,
    (freewayTolls) => freewayTolls.paymentInquiry,
  )
  freewayTolls: FreewayTollEntity[];

  @ManyToOne(() => UserEntity, (users) => users.payments, {
    onDelete: 'NO ACTION',
    onUpdate: 'NO ACTION',
  })
  @JoinColumn([{ name: 'userId', referencedColumnName: 'id' }])
  user: UserEntity;

  @ManyToOne(() => OrderEntity, (orders) => orders.payments, {
    onDelete: 'NO ACTION',
    onUpdate: 'CASCADE',
  })
  @JoinColumn([{ name: 'orderId', referencedColumnName: 'id' }])
  order: OrderEntity;
}
