package takeover

import (
	"time"

	"gorm.io/gorm"

	basedomain "wucher/internal/domain/base"
	filemanager "wucher/internal/domain/file_manager"
	reserveac "wucher/internal/domain/reserve_ac"
	userdomain "wucher/internal/domain/user"
	"wucher/internal/shared/pkg/uuidv7"
)

type TakeoverAc struct {
	ID          []byte  `gorm:"type:binary(16);primaryKey;column:id"`
	BaseID      []byte  `gorm:"type:binary(16);column:base_id"`
	ReserveAcID []byte  `gorm:"type:binary(16);index;column:reserve_ac_id"`
	Notes       *string `gorm:"type:text;column:notes"`

	Base        *basedomain.Base      `gorm:"foreignKey:BaseID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	ReserveAc   *reserveac.ReserveAc  `gorm:"foreignKey:ReserveAcID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	RosterCrews []TakeoverRosterCrew  `gorm:"foreignKey:TakeoverID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	OtherPeople []TakeoverOtherPerson `gorm:"foreignKey:TakeoverID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	Files       []TakeoverFile        `gorm:"foreignKey:TakeoverID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`

	CreatedAt time.Time  `gorm:"column:created_at"`
	CreatedBy []byte     `gorm:"type:binary(16);column:created_by"`
	UpdatedAt time.Time  `gorm:"column:updated_at"`
	UpdatedBy []byte     `gorm:"type:binary(16);column:updated_by"`
	DeletedAt *time.Time `gorm:"column:deleted_at;index"`
	DeletedBy []byte     `gorm:"type:binary(16);column:deleted_by"`
}

func (TakeoverAc) TableName() string { return "takeover_acs" }

func (t *TakeoverAc) BeforeCreate(_ *gorm.DB) error {
	if len(t.ID) == 0 {
		t.ID = uuidv7.MustBytes()
	}
	return nil
}

type TakeoverRosterCrew struct {
	ID               []byte     `gorm:"type:binary(16);primaryKey;column:id"`
	TakeoverID       []byte     `gorm:"type:binary(16);index:idx_takeover_roster_crews_takeover_id;column:takeover_id"`
	ConfirmAt        *time.Time `gorm:"column:confirm_at"`
	RoleCode         string     `gorm:"type:varchar(64);not null;index:idx_takeover_roster_crews_unique,unique;column:role_code"`
	CrewType         string     `gorm:"type:varchar(32);not null;default:main;index:idx_takeover_roster_crews_unique,unique;column:crew_type"`
	UserID           []byte     `gorm:"type:binary(16);index:idx_takeover_roster_crews_unique,unique;column:user_id"`
	User             *userdomain.User `gorm:"foreignKey:UserID;references:ID;constraint:-" json:"user,omitempty"`
	NameLabel        string     `gorm:"type:varchar(191);index:idx_takeover_roster_crews_unique,unique;column:name_label" json:"name"`
	MobilePhone      string     `gorm:"type:varchar(64);column:mobile_phone"`
	Email            string     `gorm:"type:varchar(191);column:email"`
	DateStart        *time.Time `gorm:"type:date;index:idx_takeover_roster_crews_unique,unique;column:date_start"`
	DateEnd          *time.Time `gorm:"type:date;index:idx_takeover_roster_crews_unique,unique;column:date_end"`
	ShiftStart       *string    `gorm:"type:time;index:idx_takeover_roster_crews_unique,unique;column:shift_start"`
	ShiftEnd         *string    `gorm:"type:time;index:idx_takeover_roster_crews_unique,unique;column:shift_end"`
	FlightInstructor bool       `gorm:"type:tinyint(1);not null;default:0;column:flight_instructor"`
	LineChecker      bool       `gorm:"type:tinyint(1);not null;default:0;column:line_checker"`
	Supervisor       bool       `gorm:"type:tinyint(1);not null;default:0;column:supervisor"`
	Examiner         bool       `gorm:"type:tinyint(1);not null;default:0;column:examiner"`
	CoPilot          bool       `gorm:"type:tinyint(1);not null;default:0;column:co_pilot"`

	CreatedAt time.Time  `gorm:"column:created_at"`
	CreatedBy []byte     `gorm:"type:binary(16);column:created_by"`
	UpdatedAt time.Time  `gorm:"column:updated_at"`
	UpdatedBy []byte     `gorm:"type:binary(16);column:updated_by"`
	DeletedAt *time.Time `gorm:"column:deleted_at"`
	DeletedBy []byte     `gorm:"type:binary(16);column:deleted_by"`
}

func (TakeoverRosterCrew) TableName() string { return "takeover_roster_crews" }

func (h *TakeoverRosterCrew) BeforeCreate(tx *gorm.DB) error {
	if len(h.ID) == 0 {
		h.ID = uuidv7.MustBytes()
	}
	return nil
}

type TakeoverOtherPerson struct {
	ID          []byte     `gorm:"type:binary(16);primaryKey;column:id"`
	TakeoverID  []byte     `gorm:"type:binary(16);index:idx_takeover_other_people_takeover_id;column:takeover_id"`
	OtherPersonID []byte   `gorm:"type:binary(16);index;column:other_person_id"`
	Name        string     `gorm:"type:varchar(191);column:name"`
	MobilePhone string     `gorm:"type:varchar(64);column:mobile_phone"`
	Email       string     `gorm:"type:varchar(191);column:email"`
	CreatedAt   time.Time  `gorm:"column:created_at"`
	CreatedBy   []byte     `gorm:"type:binary(16);column:created_by"`
	UpdatedAt   time.Time  `gorm:"column:updated_at"`
	UpdatedBy   []byte     `gorm:"type:binary(16);column:updated_by"`
	DeletedAt   *time.Time `gorm:"column:deleted_at"`
	DeletedBy   []byte     `gorm:"type:binary(16);column:deleted_by"`
}

func (TakeoverOtherPerson) TableName() string { return "takeover_other_people" }

func (h *TakeoverOtherPerson) BeforeCreate(tx *gorm.DB) error {
	if len(h.ID) == 0 {
		h.ID = uuidv7.MustBytes()
	}
	return nil
}

type TakeoverFile struct {
	ID               []byte `gorm:"type:binary(16);primaryKey;column:id"`
	TakeoverID       []byte `gorm:"type:binary(16);not null;index;column:takeover_id"`
	FileAttachmentID []byte `gorm:"type:binary(16);not null;index;column:file_attachment_id"`

	Takeover       *TakeoverAc             `gorm:"foreignKey:TakeoverID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	FileAttachment *filemanager.Attachment `gorm:"foreignKey:FileAttachmentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}

func (TakeoverFile) TableName() string { return "takeover_files" }

func (h *TakeoverFile) BeforeCreate(tx *gorm.DB) error {
	if len(h.ID) == 0 {
		h.ID = uuidv7.MustBytes()
	}
	return nil
}
