package migrations

import (
	"doormile/models"
	"doormile/utils"
	"gorm.io/gorm"
)

func Migrate(db *gorm.DB) error {
	utils.Info("Starting database auto-migrations for 21 logistics tables...")

	err := db.AutoMigrate(
		&models.PartnerInfo{},
		&models.Hub{},
		&models.Vehicle{},
		&models.AppUser{},
		&models.MilerProfile{},
		&models.AppCustomer{},
		&models.AppCustomerLocation{},
		&models.Consignment{},
		&models.PickupBooking{},
		&models.BookingParcel{},
		&models.BookingServiceOption{},
		&models.BookingPayment{},
		&models.BookingAssignment{},
		&models.BookingVehicleRequirement{},
		&models.Tripsheet{},
		&models.TripsheetItem{},
		&models.DeliveryProof{},
		&models.Pricing{},
		&models.ConsignmentHistory{},
		&models.ConsignmentException{},
		&models.TenantLocation{},
		&models.AppLocation{},
		&models.Tenant{},
		&models.Customer{},
		&models.CustomerLocation{},
		&models.DoormileClient{},
		&models.DoormileAuth{},
		&models.CompetitorBranch{},
		&models.CarrierPricing{},
		&models.DoormilePricing{},
		&models.AgentDecision{},
		&models.HubStaffAccount{},
		&models.HubConversation{},
		&models.HubMessage{},
		&models.MilerDutyLog{},
		&models.MilerBreakLog{},
		&models.MilerSupportTicket{},
	)

	if err != nil {
		utils.Error("❌ Database migration failed", "error", err)
		return err
	}

	utils.Info("✅ Database migration completed successfully!")

	if res := db.Exec(`ALTER TABLE agent_decisions ADD COLUMN IF NOT EXISTS context_embedding vector(1536)`); res.Error != nil {
		utils.Error("❌ Failed to add context_embedding column", "error", res.Error)
	} else {
		utils.Info("✅ context_embedding vector column ready")
	}

	if res := db.Exec(`CREATE INDEX IF NOT EXISTS idx_agent_decisions_embedding ON agent_decisions USING ivfflat (context_embedding vector_cosine_ops) WITH (lists = 100)`); res.Error != nil {
		utils.Error("❌ Failed to create ivfflat index on context_embedding", "error", res.Error)
	} else {
		utils.Info("✅ ivfflat index on context_embedding ready")
	}

	// The tripsheets.status CHECK constraint predates this codebase (not derived
	// from any gorm tag) and only allowed Draft/Dispatched/Arrived/Cancelled.
	// Hub batches need an intermediate "Ready" stage before dispatch.
	db.Exec(`ALTER TABLE tripsheets DROP CONSTRAINT IF EXISTS tripsheets_status_check`)
	if res := db.Exec(`ALTER TABLE tripsheets ADD CONSTRAINT tripsheets_status_check
		CHECK (status::text = ANY (ARRAY['Draft','Ready','Dispatched','Arrived','Cancelled']::text[]))`); res.Error != nil {
		utils.Error("❌ Failed to widen tripsheets_status_check constraint", "error", res.Error)
	} else {
		utils.Info("✅ tripsheets_status_check constraint includes Ready")
	}

	return nil
}
