import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { ItemEntity } from '../../domain/entities/item.entity';
import {
  Column,
  Entity,
  JoinColumn,
  JoinTable,
  ManyToMany,
  ManyToOne,
  OneToMany,
} from 'typeorm';
import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model';
import { ItemType } from 'src/modules/item-related/item-category/constants';
import { LimitType } from '../../constants';
import { ItemCategoryModel } from 'src/modules/item-related/item-category/data/models/item-category.model';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { ItemRateModel } from 'src/modules/item-related/item-rate/data/models/item-rate.model';
import { GateModel } from 'src/modules/web-information/gate/data/models/gate.model';
import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model';
import { TimeGroupModel } from 'src/modules/item-related/time-group/data/models/time-group.model';
import { UsageType } from 'src/modules/item-related/item-queue/constants';

@Entity(TABLE_NAME.ITEM)
export class ItemModel
  extends BaseStatusModel<ItemEntity>
  implements ItemEntity
{
  @Column('varchar', { name: 'name' })
  name: string;

  @Column('text', { name: 'booking_description', nullable: true })
  booking_description: string;

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

  @Column('json', { nullable: true })
  video_url: string[];

  @Column('enum', {
    name: 'item_type',
    enum: ItemType,
    default: ItemType.TIKET_MASUK,
  })
  item_type: ItemType;

  @Column('enum', {
    name: 'usage_type',
    enum: UsageType,
    default: UsageType.ONE_TIME,
  })
  usage_type: UsageType;

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

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

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

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

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

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

  @Column('boolean', { name: 'use_queue', default: false })
  use_queue: boolean;

  @Column('boolean', { name: 'show_to_booking', default: false })
  show_to_booking: boolean;

  @Column('boolean', { name: 'breakdown_bundling', default: false })
  breakdown_bundling: boolean;

  @Column('enum', {
    name: 'limit_type',
    enum: LimitType,
    default: LimitType.NO_LIMIT,
  })
  limit_type: LimitType;

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

  // relation ke item category
  @Column('varchar', { name: 'item_category_id', nullable: true })
  item_category_id: number;
  @ManyToOne(() => ItemCategoryModel, (model) => model.items, {
    onUpdate: 'CASCADE',
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'item_category_id' })
  item_category: ItemCategoryModel;

  // start relation to time group
  @Column('varchar', { name: 'time_group_id', nullable: true })
  time_group_id: number;
  @ManyToOne(() => TimeGroupModel, (model) => model.items, {
    onUpdate: 'CASCADE',
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'time_group_id' })
  time_group: TimeGroupModel;
  // end relation to time group

  @ManyToOne(() => ItemQueueModel, (model) => model.items, {
    onUpdate: 'CASCADE',
    onDelete: 'SET NULL',
  })
  @JoinColumn({ name: 'item_queue_id' })
  item_queue: ItemQueueModel;

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

  // relation ke tenant
  // ? karena item bisajadi merupakan item dari tenant
  @Column('varchar', { name: 'tenant_id', nullable: true })
  tenant_id: number;
  @ManyToOne(() => UserModel, (model) => model.items, {
    onUpdate: 'CASCADE',
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'tenant_id' })
  tenant: UserModel;

  // relasi ke diri sendiri
  // ?type bundling bisa punya relasi ke item (item adalah diri sendiri)
  @ManyToMany(() => ItemModel, (model) => model.bundling_items, {
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  @JoinTable({
    name: 'item_bundlings',
    joinColumn: {
      name: 'item_bundling_id',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'item_id',
      referencedColumnName: 'id',
    },
  })
  bundling_items: ItemModel[];

  // relasi ke item rates
  @OneToMany(() => ItemRateModel, (model) => model.item, {
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  item_rates: ItemRateModel[];

  // relasi ke gate
  @OneToMany(() => GateModel, (model) => model.item, {
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  gates: GateModel[];

  // relasi untuk mendapatkan parent bundling
  @ManyToMany(() => ItemModel, (model) => model.bundling_parents)
  @JoinTable({
    name: 'item_bundlings',
    joinColumn: {
      name: 'item_id',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'item_bundling_id',
      referencedColumnName: 'id',
    },
  })
  bundling_parents: ItemModel[];
}
