package actionsignoff

import (
	"time"

	"gorm.io/gorm"

	flightdomain "wucher/internal/domain/flight"
	helicopter "wucher/internal/domain/helicopter"
	"wucher/internal/shared/pkg/uuidv7"
)

// ActionSignoff is a corrective-action sign-off for a helicopter. When linked to a
// complaint (ComplaintID set) it records that the complaint's corrective action was
// signed off; when unlinked (ComplaintID nil) it is a complaint-independent duty
// sign-off (gating the EASA maintenance release even without a complaint). There is
// one row per complaint, and one current unlinked row per helicopter.
type ActionSignoff struct {
	ID           []byte `gorm:"type:binary(16);primaryKey;column:id"`
	HelicopterID []byte `gorm:"type:binary(16);not null;index;column:helicopter_id"`
	// FlightID scopes the standalone (complaint-independent) sign-off to a flight,
	// so it no longer leaks across takeovers of the same aircraft. Nullable; unset
	// for complaint-linked rows (those are keyed by complaint_id).
	FlightID []byte `gorm:"type:binary(16);index;column:flight_id"`
	// ComplaintID unique (NULLs distinct in MySQL) → one sign-off per complaint;
	// standalone rows (NULL) are unconstrained here and instead deduped per flight
	// by the functional unique index uidx_action_signoffs_standalone_flight.
	ComplaintID []byte `gorm:"type:binary(16);uniqueIndex:uidx_action_signoffs_complaint_id;column:complaint_id"`

	SignedAt *time.Time `gorm:"type:datetime(3);column:signed_at"`
	SignedBy []byte     `gorm:"type:binary(16);column:signed_by"`

	Helicopter *helicopter.Helicopter `gorm:"foreignKey:HelicopterID;references:ID"`
	Flight     *flightdomain.Flight   `gorm:"foreignKey:FlightID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`

	CreatedAt time.Time `gorm:"type:datetime(3);column:created_at"`
	UpdatedAt time.Time `gorm:"type:datetime(3);column:updated_at"`
}

func (ActionSignoff) TableName() string { return "action_signoffs" }

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

func (a *ActionSignoff) IsSigned() bool { return a != nil && a.SignedAt != nil }
