package operation

import (
	"time"

	"gorm.io/gorm"

	"wucher/internal/domain/federal_state"
	filemanager "wucher/internal/domain/file_manager"
	"wucher/internal/domain/forces_present"
	"wucher/internal/domain/land"
	"wucher/internal/domain/vocation"
	"wucher/internal/shared/pkg/uuidv7"
)

type HEMSOperationalData struct {
	ID   []byte    `json:"id" gorm:"type:binary(16);primaryKey;column:id"`
	Time time.Time `json:"time" gorm:"column:time;not null" example:"2026-03-12T03:04:05Z"`

	// Place of Appeal
	LandID     []byte `json:"land_id,omitempty" gorm:"type:binary(16);column:land_id;index"`
	VocationID []byte `json:"vocation_id,omitempty" gorm:"type:binary(16);column:vocation_id;index"`
	StateID    []byte `json:"state_id,omitempty" gorm:"type:binary(16);column:state_id;index"`
	Location   string `json:"location" gorm:"type:varchar(255);not null;column:location" example:"123 Main St, Anytown, USA"`
	Postcode   string `json:"postcode,omitempty" gorm:"type:varchar(32);column:postcode" example:"12345"`
	Notes      string `json:"notes" gorm:"type:text;column:notes" example:"Notes about the operational data"`

	// Difficulties
	Darkness          bool `json:"darkness" gorm:"type:boolean;not null;default:false;column:darkness"`
	FalseInformation  bool `json:"false_information" gorm:"type:boolean;not null;default:false;column:false_information"`
	Fog               bool `json:"fog" gorm:"type:boolean;not null;default:false;column:fog"`
	Precipitation     bool `json:"precipitation" gorm:"type:boolean;not null;default:false;column:precipitation"`
	MountainUse       bool `json:"mountain_use" gorm:"type:boolean;not null;default:false;column:mountain_use"`
	Wind              bool `json:"wind" gorm:"type:boolean;not null;default:false;column:wind"`
	NFOSearch         bool `json:"nfo_search" gorm:"type:boolean;not null;default:false;column:nfo_search"`
	LandingSiteSearch bool `json:"landing_site_search" gorm:"type:boolean;not null;default:false;column:landing_site_search"`

	// Emergency Location Features
	Temperature      float64 `json:"temperature" gorm:"type:double;not null;default:0;column:temperature" example:"23.5"`
	Altitude         float64 `json:"altitude" gorm:"type:double;not null;default:0;column:altitude" example:"5.2"`
	TerrainIndex     string  `json:"terrain_index" gorm:"type:varchar(255);column:terrain_index" enum:"Only helicopter landing | Paved road | Unpaved road | Direct access not possible | Hospitals | Landing impossible | Winches or rope recovery | Extreme salvage operation"`
	RopeRecovery     bool    `json:"rope_recovery" gorm:"type:boolean;not null;default:false;column:rope_recovery"`
	NightFlight      bool    `json:"night_flight" gorm:"type:boolean;not null;default:false;column:night_flight"`
	InstrumentFlight bool    `json:"instrument_flight" gorm:"type:boolean;not null;default:false;column:instrument_flight"`

	AdditionalInfo string `json:"additional_info" gorm:"type:text;column:additional_info" example:"Additional information about the operational data"`

	Land          *land.Land                    `json:"land,omitempty" gorm:"foreignKey:LandID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	Vocation      *vocation.Vocation            `json:"vocation,omitempty" gorm:"foreignKey:VocationID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	ForcePresents []OperationalDataForcePresent `json:"force_presents,omitempty" gorm:"foreignKey:OperationalDataID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	State         *federal_state.FederalState   `json:"state,omitempty" gorm:"foreignKey:StateID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	Files         []OperationalFile             `json:"files,omitempty" gorm:"foreignKey:OperationalDataID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`

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

func (HEMSOperationalData) TableName() string { return "hems_operational_data" }

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

type OperationalDataForcePresent struct {
	ID                []byte                        `json:"id" gorm:"type:binary(16);primaryKey;column:id"`
	OperationalDataID []byte                        `json:"operational_data_id" gorm:"type:binary(16);not null;column:operational_data_id;index:idx_hems_operational_force_present_data_id;uniqueIndex:uq_hems_operational_force_present,priority:1"`
	ForcePresentID    []byte                        `json:"force_present_id" gorm:"type:binary(16);not null;column:force_present_id;index:idx_hems_operational_force_present_fp_id;uniqueIndex:uq_hems_operational_force_present,priority:2"`
	OperationalData   *HEMSOperationalData          `json:"operational_data,omitempty" gorm:"foreignKey:OperationalDataID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	ForcePresent      *forces_present.ForcesPresent `json:"force_present,omitempty" gorm:"foreignKey:ForcePresentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	CreatedAt         time.Time                     `json:"created_at,omitempty" gorm:"column:created_at"`
	UpdatedAt         time.Time                     `json:"updated_at,omitempty" gorm:"column:updated_at"`
}

func (OperationalDataForcePresent) TableName() string { return "hems_operational_data_forces_present" }

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

type OperationalFile struct {
	ID                []byte                  `json:"id" gorm:"type:binary(16);primaryKey;column:id"`
	OperationalDataID []byte                  `json:"operational_data_id" gorm:"type:binary(16);not null;column:operational_data_id;index:idx_hems_operational_files_data_id;uniqueIndex:uq_hems_operational_file,priority:1"`
	FileAttachmentID  []byte                  `json:"file_attachment_id" gorm:"type:binary(16);not null;column:file_attachment_id;index:idx_hems_operational_files_attachment_id;uniqueIndex:uq_hems_operational_file,priority:2"`
	OperationalData   *HEMSOperationalData    `json:"operational_data,omitempty" gorm:"foreignKey:OperationalDataID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	FileAttachment    *filemanager.Attachment `json:"file_attachment,omitempty" gorm:"foreignKey:FileAttachmentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	CreatedAt         time.Time               `json:"created_at,omitempty" gorm:"column:created_at"`
	UpdatedAt         time.Time               `json:"updated_at,omitempty" gorm:"column:updated_at"`
}

func (OperationalFile) TableName() string { return "hems_operational_files" }

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