import { FindOptions, Transaction } from 'sequelize'
import {
  AllowNull,
  BelongsTo,
  Column,
  CreatedAt,
  DataType,
  ForeignKey,
  Table,
  UpdatedAt
} from 'sequelize-typescript'
import { SequelizeModel } from '../shared/index.js'
import { EventModel } from './event.js'

@Table({
  tableName: 'eventRegistration',
  indexes: [
    {
      fields: [ 'eventId' ]
    }
  ]
})
export class EventRegistrationModel extends SequelizeModel<EventRegistrationModel> {
  @AllowNull(false)
  @Column(DataType.STRING(255))
  declare firstName: string

  @AllowNull(false)
  @Column(DataType.STRING(255))
  declare lastName: string

  @AllowNull(false)
  @Column(DataType.STRING(320))
  declare email: string

  @AllowNull(false)
  @Column(DataType.STRING(50))
  declare phone: string

  @AllowNull(false)
  @Column(DataType.STRING(255))
  declare companyName: string

  @AllowNull(false)
  @Column(DataType.STRING(255))
  declare jobTitle: string

  @AllowNull(false)
  @Column(DataType.STRING(100))
  declare country: string

  @CreatedAt
  declare createdAt: Date

  @UpdatedAt
  declare updatedAt: Date

  @ForeignKey(() => EventModel)
  @Column
  declare eventId: number

  @BelongsTo(() => EventModel, {
    foreignKey: {
      allowNull: false
    },
    onDelete: 'CASCADE'
  })
  declare Event: Awaited<EventModel>

  static listForApi (options: {
    eventId: number
    start: number
    count: number
  }) {
    const { eventId, start, count } = options

    const query: FindOptions = {
      where: {
        eventId
      },
      order: [ [ 'createdAt', 'DESC' ] ],
      offset: start,
      limit: count
    }

    return EventRegistrationModel.findAndCountAll(query)
  }

  static loadByIdAndEventId (registrationId: number, eventId: number, transaction?: Transaction) {
    return EventRegistrationModel.findOne({
      where: {
        id: registrationId,
        eventId
      },
      transaction
    })
  }

  toFormattedJSON (this: EventRegistrationModel) {
    return {
      id: this.id,
      firstName: this.firstName,
      lastName: this.lastName,
      email: this.email,
      phone: this.phone,
      companyName: this.companyName,
      jobTitle: this.jobTitle,
      country: this.country,
      eventId: this.eventId,
      createdAt: this.createdAt.toISOString(),
      updatedAt: this.updatedAt.toISOString()
    }
  }
}
