package mission

import (
	"strings"
	"time"

	"gorm.io/gorm"

	filemanager "wucher/internal/domain/file_manager"
	"wucher/internal/domain/flight"
	"wucher/internal/shared/pkg/uuidv7"
)

type Mission struct {
	ID                []byte `gorm:"type:binary(16);primaryKey;column:id"`
	FlightID          []byte `gorm:"type:binary(16);not null;index;column:flight_id"`
	FlightDataID      []byte `gorm:"type:binary(16);index;column:flight_data_id"`
	MissionCategoryID []byte `gorm:"type:binary(16);index;column:mission_category_id"`
	SubtypeID         []byte `gorm:"type:binary(16);index;column:subtype_id"`
	Type             string `gorm:"type:varchar(20);not null;index;column:type"`
	Code             string `gorm:"type:varchar(32);index;column:code"`
	Note             string `gorm:"type:varchar(255);column:note"`
	StartTime        string `gorm:"type:time;column:start_time"`
	EndTime          string `gorm:"type:time;column:end_time"`
	FlightDataStatus string `gorm:"->;column:flight_data_status"`

	Flight             *flight.Flight      `gorm:"foreignKey:FlightID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	MissionCategory    *MissionCategory    `gorm:"foreignKey:MissionCategoryID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	MissionSubCategory *MissionSubCategory `gorm:"foreignKey:SubtypeID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	Files              []MissionFile       `gorm:"foreignKey:MissionID;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 (Mission) TableName() string { return "missions" }

type ListFilter struct {
	Search           string
	Sort             string
	FlightID         []byte
	FlightDataStatus string
	StartDate        *time.Time
	EndDate          *time.Time
	MissionType      string
	PilotID          []byte
	HelicopterID     []byte
}

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

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

func (MissionFile) TableName() string { return "mission_files" }

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

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

type MissionCategory struct {
	ID       []byte `gorm:"type:binary(16);primaryKey;column:id"`
	CodeType string `gorm:"type:varchar(20);not null;uniqueIndex:uidx_mission_categories_code;column:code_type"`
	TypeName string `gorm:"type:varchar(128);not null;column:name"`

	SubCategory []MissionSubCategory `gorm:"foreignKey:MissionCategoryID;references:ID"`
}

func (MissionCategory) TableName() string { return "mission_categories" }

func (c *MissionCategory) BeforeCreate(_ *gorm.DB) error {
	if len(c.ID) == 0 {
		c.ID = uuidv7.MustBytes()
	}
	c.CodeType = strings.ToUpper(strings.TrimSpace(c.CodeType))
	c.TypeName = strings.TrimSpace(c.TypeName)
	return nil
}

type MissionSubCategory struct {
	ID                []byte `gorm:"type:binary(16);primaryKey;column:id"`
	MissionCategoryID []byte `gorm:"type:binary(16);not null;index;column:mission_category_id"`
	SubCodeType       string `gorm:"type:varchar(32);not null;index;column:sub_type"`
	SubTypeName       string `gorm:"type:varchar(128);not null;column:name"`
	TaskName          string `gorm:"type:varchar(255);not null;column:task_name"`

	MissionCategory *MissionCategory `gorm:"foreignKey:MissionCategoryID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}

func (MissionSubCategory) TableName() string { return "mission_subcategories" }

func (s *MissionSubCategory) BeforeCreate(_ *gorm.DB) error {
	if len(s.ID) == 0 {
		s.ID = uuidv7.MustBytes()
	}
	s.SubCodeType = strings.ToUpper(strings.TrimSpace(s.SubCodeType))
	s.SubTypeName = strings.TrimSpace(s.SubTypeName)
	s.TaskName = strings.TrimSpace(s.TaskName)
	return nil
}
