package helicopter_usage

import (
	"time"

	"gorm.io/gorm"

	helicopterdomain "wucher/internal/domain/helicopter"
	"wucher/internal/shared/pkg/uuidv7"
)

type HelicopterUsage struct {
	ID                   []byte                       `gorm:"type:binary(16);primaryKey;column:id"`
	HelicopterID         []byte                       `gorm:"type:binary(16);not null;uniqueIndex:uidx_helicopter_usage_helicopter_id;index;column:helicopter_id"`
	Helicopter           *helicopterdomain.Helicopter `gorm:"foreignKey:HelicopterID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT"`
	TotalLanding         float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_landing"`
	TotalAirframeHours   float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_airframe_hours"`
	TotalAirframeCycles  float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_airframe_cycles"`
	TotalEngine1Hours    float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_1_hours"`
	TotalEngine1GpcNgN1  float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_1_gpc_ng_n1"`
	TotalEngine1PtcNfN2  float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_1_ptc_nf_n2"`
	TotalEngine1Ccc      float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_1_ccc"`
	TotalEngine2Hours    float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_2_hours"`
	TotalEngine2GpcNgN1  float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_2_gpc_ng_n1"`
	TotalEngine2PtcNfN2  float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_2_ptc_nf_n2"`
	TotalEngine2Ccc      float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_engine_2_ccc"`
	TotalFlightReport    float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_flight_report"`
	TotalHookRelease     float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_hook_release"`
	TotalRotorBrakeCycle float64                      `gorm:"type:decimal(12,2);not null;default:0;column:total_rotor_brake_cycle"`

	ManualAirframeHours   float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_airframe_hours"`
	ManualAirframeCycles  float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_airframe_cycles"`
	ManualEngine1Hours    float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_1_hours"`
	ManualEngine1GpcNgN1  float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_1_gpc_ng_n1"`
	ManualEngine1PtcNfN2  float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_1_ptc_nf_n2"`
	ManualEngine2Hours    float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_2_hours"`
	ManualEngine2GpcNgN1  float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_2_gpc_ng_n1"`
	ManualEngine2PtcNfN2  float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_engine_2_ptc_nf_n2"`
	ManualLanding         float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_landing"`
	ManualFlightReport    float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_flight_report"`
	ManualHookRelease     float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_hook_release"`
	ManualRotorBrakeCycle float64 `gorm:"type:decimal(12,2);not null;default:0;column:manual_rotor_brake_cycle"`

	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 (HelicopterUsage) TableName() string { return "helicopter_usage" }

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

type ManualSummaryInput struct {
	AirframeHours   *float64
	AirframeCycles  *float64
	Engine1Hours    *float64
	Engine1GpcNgN1  *float64
	Engine1PtcNfN2  *float64
	Engine1Ccc      *float64
	Engine2Hours    *float64
	Engine2GpcNgN1  *float64
	Engine2PtcNfN2  *float64
	Engine2Ccc      *float64
	Landing         *float64
	FlightReport    *float64
	HookRelease     *float64
	RotorBrakeCycle *float64
}

func (h *HelicopterUsage) ApplyManualSummary(in ManualSummaryInput) {
	reviseFloatTotal(&h.TotalAirframeHours, &h.ManualAirframeHours, in.AirframeHours)
	reviseFloatTotal(&h.TotalAirframeCycles, &h.ManualAirframeCycles, in.AirframeCycles)
	reviseFloatTotal(&h.TotalEngine1Hours, &h.ManualEngine1Hours, in.Engine1Hours)
	reviseFloatTotal(&h.TotalEngine1GpcNgN1, &h.ManualEngine1GpcNgN1, in.Engine1GpcNgN1)
	reviseFloatTotal(&h.TotalEngine1PtcNfN2, &h.ManualEngine1PtcNfN2, in.Engine1PtcNfN2)
	reviseFloatTotal(&h.TotalEngine2Hours, &h.ManualEngine2Hours, in.Engine2Hours)
	reviseFloatTotal(&h.TotalEngine2GpcNgN1, &h.ManualEngine2GpcNgN1, in.Engine2GpcNgN1)
	reviseFloatTotal(&h.TotalEngine2PtcNfN2, &h.ManualEngine2PtcNfN2, in.Engine2PtcNfN2)
	reviseFloatTotal(&h.TotalLanding, &h.ManualLanding, in.Landing)
	reviseFloatTotal(&h.TotalFlightReport, &h.ManualFlightReport, in.FlightReport)
	reviseFloatTotal(&h.TotalHookRelease, &h.ManualHookRelease, in.HookRelease)
	reviseFloatTotal(&h.TotalRotorBrakeCycle, &h.ManualRotorBrakeCycle, in.RotorBrakeCycle)
	if in.Engine1Ccc != nil {
		h.TotalEngine1Ccc = *in.Engine1Ccc
	}
	if in.Engine2Ccc != nil {
		h.TotalEngine2Ccc = *in.Engine2Ccc
	}
}

func reviseFloatTotal(total, manual, desired *float64) {
	if desired == nil {
		return
	}
	*manual += *desired - *total
	*total = *desired
}
