import { BooleanTransformer } from 'src/utils/transformers/BooleanTransformer';
import {
  BaseEntity,
  Column,
  Entity,
  Index,
  JoinColumn,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
} from 'typeorm';
import { OrderEntity } from '../../order/entities/order.entity';
import { UserEntity } from '../../user/entities/user.entity';
import { MakerBrandEntity } from './maker-brand.entity';
import { DrivingOffenseEntity } from '../../drivinig-offense/entities/driving-offense.entity';
import { FreewayTollEntity } from '../../freeway-toll/entities/freeway-toll.entity';
import { InsuranceThirdPartyInquiryEntity } from '../../insurance/entities/insurance-third-party-inquiry.entity';

export enum CarType {
  private = 'private',
  organization = 'organization',
  disposal = 'disposal',
}

@Index('makerBrandId', ['makerBrandId'], {})
@Index('userId', ['userId'], {})
@Entity('cars')
export class CarEntity extends BaseEntity {
  @PrimaryGeneratedColumn({ type: 'int', name: 'id' })
  id: number;

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

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

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

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

  @Column('enum', {
    name: 'type',
    enum: CarType,
    default: () => CarType.private,
  })
  type: CarType;

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

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

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

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

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

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

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

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

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

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

  @Column('datetime', { name: 'oilGovLastChecked', nullable: true })
  oilGovLastChecked: Date | null;

  @Column('datetime', { name: 'oilGovSuccessChecked', nullable: true })
  oilGovSuccessChecked: Date | null;

  @Column('tinyint', { name: 'oilGovForce', width: 1, default: () => "'0'" })
  oilGovForce: boolean | null;

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

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

  @Column('tinyint', {
    name: 'deleted',
    nullable: true,
    width: 1,
    default: () => "'0'",
    transformer: new BooleanTransformer(),
  })
  deleted: boolean | null;

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

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

  /**
   * relations
   */
  @ManyToOne(() => MakerBrandEntity, (makerbrands) => makerbrands.cars, {
    onDelete: 'NO ACTION',
    onUpdate: 'CASCADE',
  })
  @JoinColumn([{ name: 'makerBrandId', referencedColumnName: 'id' }])
  makerBrand: MakerBrandEntity;

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

  @OneToMany(() => OrderEntity, (orders) => orders.car)
  orders: OrderEntity[];

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

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

  @OneToMany(
    () => InsuranceThirdPartyInquiryEntity,
    (insuranceThirdPartyInquiries) => insuranceThirdPartyInquiries.car,
  )
  insuranceThirdPartyInquiries: InsuranceThirdPartyInquiryEntity[];
}
