package seeders

import (
	"encoding/json"
	"fmt"
	"time"

	"payment/internal/models"

	"github.com/google/uuid"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// jsonMarshal is a helper function to marshal data to JSON
func jsonMarshal(data interface{}) ([]byte, error) {
	return json.Marshal(data)
}

// Helper functions for pointer types
func intPtr(i int) *int {
	return &i
}

func stringPtr(s string) *string {
	return &s
}

func float64Ptr(f float64) *float64 {
	return &f
}

// SeedDatabase seeds all tables with sample data
func SeedDatabase(db *gorm.DB) error {
	if err := seedClients(db); err != nil {
		return fmt.Errorf("error seeding clients: %w", err)
	}
	if err := seedUsers(db); err != nil {
		return fmt.Errorf("error seeding users: %w", err)
	}
	if err := seedPaymentCredentials(db); err != nil {
		return fmt.Errorf("error seeding payment credentials: %w", err)
	}
	if err := seedInternetPackages(db); err != nil {
		return fmt.Errorf("error seeding internet packages: %w", err)
	}
	if err := seedTransactions(db); err != nil {
		return fmt.Errorf("error seeding transactions: %w", err)
	}
	if err := seedAccessTokens(db); err != nil {
		return fmt.Errorf("error seeding access tokens: %w", err)
	}
	fmt.Println("✓ Database seeded successfully")
	return nil
}

// seedClients creates sample client records
func seedClients(db *gorm.DB) error {
	var count int64
	db.Model(&models.Client{}).Count(&count)

	// Skip if clients already exist
	if count > 0 {
		fmt.Println("⊘ Clients already exist, skipping...")
		return nil
	}

	clients := []models.Client{
		{
			ID:                 uuid.New(),
			Name:               "TechCorp Kenya",
			BusinessName:       stringPtr("TechCorp"),
			BusinessType:       stringPtr("Limited Liability Company"),
			Industry:           stringPtr("Telecommunications"),
			RegistrationNumber: stringPtr("C.123456/2020"),
			TaxID:              stringPtr("P051234567K"),
			VATNumber:          stringPtr("VAT-123456"),
			Email:              "admin@techcorp.ke",
			Phone:              stringPtr("+254712345678"),
			AlternatePhone:     nil,
			Website:            stringPtr("https://techcorp.ke"),
			ContactPersonName:  stringPtr("John Doe"),
			ContactPersonEmail: stringPtr("john.doe@techcorp.ke"),
			ContactPersonPhone: stringPtr("+254712345679"),
			Address:            stringPtr("123 Tech Street, Westlands"),
			City:               stringPtr("Nairobi"),
			State:              stringPtr("Nairobi County"),
			Country:            stringPtr("Kenya"),
			PostalCode:         stringPtr("00100"),
			Description:        stringPtr("Leading telecommunications provider in Kenya"),
			Notes:              nil,
			Status:             "active",
			IsActive:           true,
			CreatedAt:          time.Now(),
			UpdatedAt:          time.Now(),
		},
		{
			ID:                 uuid.New(),
			Name:               "Digital Solutions Ltd",
			BusinessName:       stringPtr("DigSol"),
			BusinessType:       stringPtr("Private Limited Company"),
			Industry:           stringPtr("IT Services"),
			RegistrationNumber: stringPtr("C.789012/2019"),
			TaxID:              stringPtr("P059876543K"),
			VATNumber:          stringPtr("VAT-789012"),
			Email:              "contact@digsol.ke",
			Phone:              stringPtr("+254798765432"),
			AlternatePhone:     stringPtr("+254798765433"),
			Website:            stringPtr("https://digsol.ke"),
			ContactPersonName:  stringPtr("Jane Smith"),
			ContactPersonEmail: stringPtr("jane.smith@digsol.ke"),
			ContactPersonPhone: stringPtr("+254798765434"),
			Address:            stringPtr("456 Digital Avenue, Nyali"),
			City:               stringPtr("Mombasa"),
			State:              stringPtr("Mombasa County"),
			Country:            stringPtr("Kenya"),
			PostalCode:         stringPtr("80100"),
			Description:        stringPtr("Digital transformation and IT solutions provider"),
			Notes:              nil,
			Status:             "active",
			IsActive:           true,
			CreatedAt:          time.Now(),
			UpdatedAt:          time.Now(),
		},
		{
			ID:                 uuid.New(),
			Name:               "Innovation Hub",
			BusinessName:       nil, // Some fields can be null
			BusinessType:       stringPtr("Sole Proprietorship"),
			Industry:           stringPtr("Technology"),
			RegistrationNumber: stringPtr("C.345678/2021"),
			TaxID:              nil, // Nullable
			VATNumber:          nil, // Nullable
			Email:              "hello@innovationhub.ke",
			Phone:              stringPtr("+254712111111"),
			AlternatePhone:     nil,
			Website:            nil, // Nullable
			ContactPersonName:  stringPtr("Peter Kipchoge"),
			ContactPersonEmail: nil, // Nullable
			ContactPersonPhone: nil, // Nullable
			Address:            stringPtr("789 Innovation Road, Milimani"),
			City:               stringPtr("Kisumu"),
			State:              stringPtr("Kisumu County"),
			Country:            stringPtr("Kenya"),
			PostalCode:         stringPtr("40100"),
			Description:        nil, // Nullable
			Notes:              stringPtr("Startup business, monitoring growth"),
			Status:             "active",
			IsActive:           true,
			CreatedAt:          time.Now(),
			UpdatedAt:          time.Now(),
		},
	}

	if err := db.CreateInBatches(clients, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d clients\n", len(clients))
	return nil
}

// seedPaymentCredentials creates sample payment credentials
func seedPaymentCredentials(db *gorm.DB) error {
	var count int64
	db.Model(&models.PaymentCredentials{}).Count(&count)

	// Skip if credentials already exist
	if count > 0 {
		fmt.Println("⊘ Payment credentials already exist, skipping...")
		return nil
	}

	var clients []models.Client
	if err := db.Find(&clients).Error; err != nil {
		return fmt.Errorf("failed to fetch clients: %w", err)
	}

	if len(clients) == 0 {
		return fmt.Errorf("no clients found to seed credentials")
	}

	credentials := []models.PaymentCredentials{
		{
			ID:             uuid.New(),
			ClientID:       clients[0].ID,
			Provider:       "mpesa",
			ConsumerKey:    "qKX7sA5p5HZGFlrmv9pXCAH6LlZXum39kKaq7pYCsExrlmqp",
			ConsumerSecret: "YryfwB9X70wFpUytiu9h60fVLgSfuQhcPrkjp6W73G7YQRQZasLvATAGR6dZyhCu",
			ShortCode:      "174379",
			PassKey:        "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919",
			BaseURL:        "https://sandbox.safaricom.co.ke",
			CallbackURL:    "https://payment.taifaguard.co.ke/api/v1/callback/mpesa",
			IsActive:       true,
			CreatedAt:      time.Now(),
			UpdatedAt:      time.Now(),
		},
		{
			ID:             uuid.New(),
			ClientID:       clients[1].ID,
			Provider:       "mpesa",
			ConsumerKey:    "aB1cD2eF3gH4iJ5kL6mN7oP8qR9sTuVwX",
			ConsumerSecret: "yZ0a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5",
			ShortCode:      "174380",
			PassKey:        "0118201021c9dcc914f955239212c3926f1bed4442a601cd742907a14cd6419f",
			BaseURL:        "https://sandbox.safaricom.co.ke",
			CallbackURL:    "https://digsol.com/api/v1/callback/mpesa",
			IsActive:       true,
			CreatedAt:      time.Now(),
			UpdatedAt:      time.Now(),
		},
	}

	if err := db.CreateInBatches(credentials, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d payment credentials\n", len(credentials))
	return nil
}

// seedUsers creates sample user records
func seedUsers(db *gorm.DB) error {
	var count int64
	db.Model(&models.User{}).Count(&count)

	// Skip if users already exist
	if count > 0 {
		fmt.Println("⊘ Users already exist, skipping...")
		return nil
	}

	var clients []models.Client
	if err := db.Find(&clients).Error; err != nil {
		return fmt.Errorf("failed to fetch clients: %w", err)
	}

	if len(clients) == 0 {
		return fmt.Errorf("no clients found to seed users")
	}

	// Hash password helper
	hashPassword := func(password string) string {
		hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
		if err != nil {
			// Fallback to plain text if hashing fails (shouldn't happen)
			return password
		}
		return string(hashed)
	}

	now := time.Now()
	users := []models.User{
		{
			ID:        uuid.New(),
			ClientID:  clients[0].ID,
			Name:      "John Doe",
			Username:  "johndoe",
			Password:  hashPassword("password123"),
			Email:     stringPtr("john.doe@example.com"),
			Phone:     "+254712345678",
			CreatedAt: now.Add(-30 * 24 * time.Hour), // 30 days ago
			UpdatedAt: now.Add(-30 * 24 * time.Hour),
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[0].ID,
			Name:      "Jane Smith",
			Username:  "janesmith",
			Password:  hashPassword("password123"),
			Email:     stringPtr("jane.smith@example.com"),
			Phone:     "+254798765432",
			CreatedAt: now.Add(-20 * 24 * time.Hour), // 20 days ago
			UpdatedAt: now.Add(-20 * 24 * time.Hour),
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[0].ID,
			Name:      "Peter Kipchoge",
			Username:  "peterk",
			Password:  hashPassword("password123"),
			Email:     stringPtr("peter.kipchoge@example.com"),
			Phone:     "+254712111111",
			CreatedAt: now.Add(-10 * 24 * time.Hour), // 10 days ago
			UpdatedAt: now.Add(-10 * 24 * time.Hour),
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[1].ID,
			Name:      "Mary Wanjiku",
			Username:  "maryw",
			Password:  hashPassword("password123"),
			Email:     stringPtr("mary.wanjiku@example.com"),
			Phone:     "+254723456789",
			CreatedAt: now.Add(-15 * 24 * time.Hour), // 15 days ago
			UpdatedAt: now.Add(-15 * 24 * time.Hour),
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[1].ID,
			Name:      "David Ochieng",
			Username:  "davido",
			Password:  hashPassword("password123"),
			Email:     stringPtr("david.ochieng@example.com"),
			Phone:     "+254734567890",
			CreatedAt: now.Add(-5 * 24 * time.Hour), // 5 days ago
			UpdatedAt: now.Add(-5 * 24 * time.Hour),
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[0].ID,
			Name:      "Sarah Kamau",
			Username:  "sarahk",
			Password:  hashPassword("password123"),
			Email:     nil, // No email
			Phone:     "+254745678901",
			CreatedAt: now.Add(-2 * 24 * time.Hour), // 2 days ago
			UpdatedAt: now.Add(-2 * 24 * time.Hour),
		},
	}

	if err := db.CreateInBatches(users, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d users\n", len(users))
	return nil
}

// seedInternetPackages creates sample internet packages
func seedInternetPackages(db *gorm.DB) error {
	var count int64
	db.Model(&models.InternetPackage{}).Count(&count)

	// Skip if packages already exist
	if count > 0 {
		fmt.Println("⊘ Internet packages already exist, skipping...")
		return nil
	}

	var clients []models.Client
	if err := db.Find(&clients).Error; err != nil {
		return fmt.Errorf("failed to fetch clients: %w", err)
	}

	if len(clients) == 0 {
		return fmt.Errorf("no clients found to seed packages")
	}

	now := time.Now()
	packages := []models.InternetPackage{}

	// Define 8 packages per business (as per the provided template)
	packageTemplates := []struct {
		id               string
		packageType      string
		name             string
		duration         string
		durationMinutes  int
		price            float64
		description      string
		uploadSpeed      string
		downloadSpeed    string
		devices          *int
		totalLimit       *float64
		burstEnabled     bool
		burstLimit       *string
		burstThreshold   *string
		burstTime        *int
		scheduleEnabled  bool
		scheduleStart    *string
		scheduleEnd      *string
		availableDays    []string
		hiddenFromClient bool
		features         []string
		category         string
		popular          bool
	}{
		{
			id:               "1hr",
			packageType:      "Hotspot",
			name:             "1 Hour",
			duration:         "1 Hour",
			durationMinutes:  60,
			price:            20,
			description:      "Perfect for quick browsing and emails",
			uploadSpeed:      "1M",
			downloadSpeed:    "10M",
			devices:          intPtr(1),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("2M"),
			burstThreshold:   stringPtr("512k"),
			burstTime:        intPtr(10),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"High-speed internet", "Single device", "Instant activation"},
			category:         "daily",
			popular:          false,
		},
		{
			id:               "3hr",
			packageType:      "Hotspot",
			name:             "3 Hours",
			duration:         "3 Hours",
			durationMinutes:  180,
			price:            50,
			description:      "Great for streaming and social media",
			uploadSpeed:      "2M",
			downloadSpeed:    "20M",
			devices:          intPtr(1),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("4M"),
			burstThreshold:   stringPtr("1M"),
			burstTime:        intPtr(15),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"High-speed internet", "Single device", "Instant activation", "HD streaming support"},
			category:         "daily",
			popular:          false,
		},
		{
			id:               "24hr",
			packageType:      "Hotspot",
			name:             "24 Hours",
			duration:         "24 Hours",
			durationMinutes:  1440,
			price:            100,
			description:      "Full day access for work or entertainment",
			uploadSpeed:      "5M",
			downloadSpeed:    "50M",
			devices:          intPtr(2),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("10M"),
			burstThreshold:   stringPtr("2M"),
			burstTime:        intPtr(20),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"High-speed internet", "Up to 2 devices", "Instant activation", "HD streaming support", "Priority support"},
			category:         "daily",
			popular:          true,
		},
		{
			id:               "7day",
			packageType:      "Hotspot",
			name:             "7 Days",
			duration:         "7 Days",
			durationMinutes:  10080,
			price:            500,
			description:      "Weekly access for regular users",
			uploadSpeed:      "10M",
			downloadSpeed:    "100M",
			devices:          intPtr(3),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("20M"),
			burstThreshold:   stringPtr("5M"),
			burstTime:        intPtr(30),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"High-speed internet", "Up to 3 devices", "Instant activation", "HD streaming support", "Priority support", "No speed limits"},
			category:         "weekly",
			popular:          false,
		},
		{
			id:               "30day",
			packageType:      "Hotspot",
			name:             "30 Days",
			duration:         "30 Days",
			durationMinutes:  43200,
			price:            1500,
			description:      "Best value for long-term users",
			uploadSpeed:      "20M",
			downloadSpeed:    "200M",
			devices:          intPtr(5),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("50M"),
			burstThreshold:   stringPtr("10M"),
			burstTime:        intPtr(45),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"Unlimited high-speed internet", "Up to 5 devices", "Instant activation", "4K streaming support", "24/7 priority support", "No speed limits", "Guest access sharing"},
			category:         "monthly",
			popular:          false,
		},
		{
			id:               "60day",
			packageType:      "Hotspot",
			name:             "60 Days",
			duration:         "60 Days",
			durationMinutes:  86400,
			price:            2800,
			description:      "Extended access with premium features",
			uploadSpeed:      "30M",
			downloadSpeed:    "300M",
			devices:          intPtr(7),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("100M"),
			burstThreshold:   stringPtr("20M"),
			burstTime:        intPtr(60),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"Unlimited high-speed internet", "Up to 7 devices", "Instant activation", "4K streaming support", "24/7 priority support", "No speed limits", "Guest access sharing", "Family plan"},
			category:         "monthly",
			popular:          false,
		},
		{
			id:               "90day",
			packageType:      "Hotspot",
			name:             "90 Days",
			duration:         "90 Days",
			durationMinutes:  129600,
			price:            4000,
			description:      "Quarterly plan with maximum savings",
			uploadSpeed:      "50M",
			downloadSpeed:    "500M",
			devices:          intPtr(10),
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("200M"),
			burstThreshold:   stringPtr("50M"),
			burstTime:        intPtr(90),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"Unlimited high-speed internet", "Up to 10 devices", "Instant activation", "4K streaming support", "24/7 priority support", "No speed limits", "Guest access sharing", "Family plan", "Business support"},
			category:         "monthly",
			popular:          false,
		},
		{
			id:               "365day",
			packageType:      "Hotspot",
			name:             "365 Days",
			duration:         "365 Days",
			durationMinutes:  525600,
			price:            12000,
			description:      "Annual plan with best value",
			uploadSpeed:      "100M",
			downloadSpeed:    "1000M",
			devices:          nil, // Unlimited
			totalLimit:       nil,
			burstEnabled:     true,
			burstLimit:       stringPtr("500M"),
			burstThreshold:   stringPtr("100M"),
			burstTime:        intPtr(120),
			scheduleEnabled:  false,
			scheduleStart:    nil,
			scheduleEnd:      nil,
			availableDays:    []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"},
			hiddenFromClient: false,
			features:         []string{"Unlimited high-speed internet", "Unlimited devices", "Instant activation", "4K streaming support", "24/7 priority support", "No speed limits", "Guest access sharing", "Family plan", "Business support", "Annual discount"},
			category:         "monthly",
			popular:          true,
		},
	}

	// Create 8 packages for each client
	for _, client := range clients {
		for _, tmpl := range packageTemplates {
			// Convert features to JSON
			featuresJSON, _ := jsonMarshal(tmpl.features)
			featuresStr := string(featuresJSON)

			// Convert available days to JSON
			var availableDaysStr *string
			if len(tmpl.availableDays) > 0 {
				daysJSON, _ := jsonMarshal(tmpl.availableDays)
				daysStr := string(daysJSON)
				availableDaysStr = &daysStr
			}

			// Calculate legacy speed field for backward compatibility
			legacySpeed := fmt.Sprintf("%s/%s", tmpl.downloadSpeed, tmpl.uploadSpeed)

			package_ := models.InternetPackage{
				ID:                uuid.New(),
				ClientID:          client.ID,
				PackageType:       tmpl.packageType,
				Name:              tmpl.name,
				Description:       tmpl.description,
				Duration:          tmpl.duration,
				DurationMinutes:   tmpl.durationMinutes,
				UploadSpeed:       tmpl.uploadSpeed,
				DownloadSpeed:     tmpl.downloadSpeed,
				Speed:             legacySpeed, // Legacy field for backward compatibility
				Amount:            tmpl.price,
				Currency:          "KES",
				Devices:           tmpl.devices,
				TotalLimit:        tmpl.totalLimit,
				BurstEnabled:      tmpl.burstEnabled,
				BurstLimit:        tmpl.burstLimit,
				BurstThreshold:    tmpl.burstThreshold,
				BurstTime:         tmpl.burstTime,
				ScheduleEnabled:   tmpl.scheduleEnabled,
				ScheduleStartTime: tmpl.scheduleStart,
				ScheduleEndTime:   tmpl.scheduleEnd,
				AvailableDays:     availableDaysStr,
				HiddenFromClient:  tmpl.hiddenFromClient,
				Features:          &featuresStr,
				Category:          tmpl.category,
				Popular:           &tmpl.popular,
				IsActive:          true,
				CreatedAt:         now,
				UpdatedAt:         now,
			}
			packages = append(packages, package_)
		}
	}

	if err := db.CreateInBatches(packages, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d internet packages (%d per business)\n", len(packages), len(packageTemplates))
	return nil
}

// seedTransactions creates sample transaction records
func seedTransactions(db *gorm.DB) error {
	var count int64
	db.Model(&models.Transaction{}).Count(&count)

	// Skip if transactions already exist
	if count > 0 {
		fmt.Println("⊘ Transactions already exist, skipping...")
		return nil
	}

	var clients []models.Client
	if err := db.Find(&clients).Error; err != nil {
		return fmt.Errorf("failed to fetch clients: %w", err)
	}

	if len(clients) == 0 {
		return fmt.Errorf("no clients found to seed transactions")
	}

	// Fetch users to attach to transactions
	var users []models.User
	if err := db.Find(&users).Error; err != nil {
		return fmt.Errorf("failed to fetch users: %w", err)
	}

	// Fetch internet packages to attach to transactions
	var packages []models.InternetPackage
	if err := db.Where("is_active = ?", true).Find(&packages).Error; err != nil {
		return fmt.Errorf("failed to fetch internet packages: %w", err)
	}

	if len(packages) == 0 {
		return fmt.Errorf("no internet packages found to seed transactions")
	}

	now := time.Now()
	metadata := `{"package_id":"starter","user_id":"user123"}`
	providerResponse := `{"resultCode":0,"resultDesc":"The service request has been accepted for processing"}`

	transactions := []models.Transaction{}

	// Create transactions with users attached (if users exist)
	if len(users) > 0 {
		// Transaction 1 - Attached to first user and first package
		packageID1 := packages[0].ID
		transactions = append(transactions, models.Transaction{
			ID:               uuid.New(),
			ClientID:         clients[0].ID,
			UserID:           &users[0].ID, // Attach to first user
			PackageID:        &packageID1,  // Attach to first package
			CheckoutID:       uuid.New().String(),
			Amount:           500,
			Currency:         "KES",
			PaymentMethod:    "mpesa",
			PaymentStatus:    "completed",
			PhoneNumber:      "+254712345678",
			Reference:        "REF001",
			MpesaReceipt:     "LHD21AS9D2",
			Description:      "Internet package - Starter Plan",
			Metadata:         &metadata,
			Provider:         "mpesa",
			ProviderResponse: &providerResponse,
			CreatedAt:        now.Add(-72 * time.Hour),
			UpdatedAt:        now.Add(-72 * time.Hour),
		})

		// Transaction 2 - Attached to second user and second package (or first if only one)
		if len(users) > 1 {
			packageID2 := packages[0].ID
			if len(packages) > 1 {
				packageID2 = packages[1].ID
			}
			transactions = append(transactions, models.Transaction{
			ID:            uuid.New(),
			ClientID:      clients[0].ID,
				UserID:        &users[1].ID,  // Attach to second user
				PackageID:     &packageID2,  // Attach to package
				CheckoutID:    uuid.New().String(),
				Amount:        1500,
				Currency:      "KES",
				PaymentMethod: "mpesa",
				PaymentStatus: "completed",
				PhoneNumber:   "+254798765432",
				Reference:     "REF002",
				MpesaReceipt:  "LHD21AS9D3",
				Description:   "Internet package - Professional Plan",
				Metadata:      &metadata,
				Provider:      "mpesa",
				CreatedAt:     now.Add(-48 * time.Hour),
				UpdatedAt:     now.Add(-48 * time.Hour),
			})
		}

		// Transaction 3 - Attached to third user (if exists) and a package
		if len(users) > 2 {
			packageID3 := packages[0].ID
			if len(packages) > 2 {
				packageID3 = packages[2].ID
			}
			transactions = append(transactions, models.Transaction{
				ID:            uuid.New(),
				ClientID:      clients[1].ID,
				UserID:        &users[2].ID,  // Attach to third user
				PackageID:     &packageID3,   // Attach to package
				CheckoutID:    uuid.New().String(),
				Amount:        450,
				Currency:      "KES",
				PaymentMethod: "mpesa",
				PaymentStatus: "pending",
				PhoneNumber:   "+254712111111",
				Reference:     "REF003",
				Description:   "Internet package - Basic Package",
				Metadata:      &metadata,
				Provider:      "mpesa",
				CreatedAt:     now,
				UpdatedAt:     now,
			})
		}

		// Transaction 4 - Attached to fourth user (if exists) and a package
		if len(users) > 3 {
			packageID4 := packages[0].ID
			if len(packages) > 3 {
				packageID4 = packages[3].ID
			}
			transactions = append(transactions, models.Transaction{
				ID:            uuid.New(),
				ClientID:      clients[0].ID,
				UserID:        &users[3].ID,  // Attach to fourth user
				PackageID:     &packageID4,   // Attach to package
				CheckoutID:    uuid.New().String(),
				Amount:        5000,
				Currency:      "KES",
				PaymentMethod: "mpesa",
				PaymentStatus: "completed",
				PhoneNumber:   "+254712345678",
				Reference:     "REF004",
				MpesaReceipt:  "LHD21AS9D4",
				Description:   "Internet package - Enterprise Plan",
				Metadata:      &metadata,
				Provider:      "mpesa",
				CreatedAt:     now.Add(-24 * time.Hour),
				UpdatedAt:     now.Add(-24 * time.Hour),
			})
		}

		// Transaction 5 - No user attached (nullable) but has package
		packageID5 := packages[0].ID
		if len(packages) > 1 {
			packageID5 = packages[1].ID
		}
		transactions = append(transactions, models.Transaction{
			ID:            uuid.New(),
			ClientID:      clients[0].ID,
			UserID:        nil,      // No user attached
			PackageID:     &packageID5, // Attach to package
			CheckoutID:    uuid.New().String(),
			Amount:        250,
			Currency:      "KES",
			PaymentMethod: "mpesa",
			PaymentStatus: "completed",
			PhoneNumber:   "+254756789012",
			Reference:     "REF005",
			MpesaReceipt:  "LHD21AS9D5",
			Description:   "Internet package - Basic Plan",
			Metadata:      &metadata,
			Provider:      "mpesa",
			CreatedAt:     now.Add(-12 * time.Hour),
			UpdatedAt:     now.Add(-12 * time.Hour),
		})

		// Transaction 6 - Attached to fifth user (if exists) and a package
		if len(users) > 4 {
			packageID6 := packages[0].ID
			if len(packages) > 4 {
				packageID6 = packages[4].ID
			}
			transactions = append(transactions, models.Transaction{
				ID:            uuid.New(),
				ClientID:      clients[1].ID,
				UserID:        &users[4].ID,  // Attach to fifth user
				PackageID:     &packageID6,    // Attach to package
				CheckoutID:    uuid.New().String(),
				Amount:        750,
				Currency:      "KES",
				PaymentMethod: "mpesa",
				PaymentStatus: "pending",
				PhoneNumber:   "+254734567890",
				Reference:     "REF006",
				Description:   "Internet package - Standard Plan",
				Metadata:      &metadata,
				Provider:      "mpesa",
				CreatedAt:     now.Add(-6 * time.Hour),
				UpdatedAt:     now.Add(-6 * time.Hour),
			})
		}
	} else {
		// If no users exist, create transactions without user_id
		transactions = []models.Transaction{
			{
				ID:               uuid.New(),
				ClientID:         clients[0].ID,
				UserID:           nil,
				CheckoutID:       uuid.New().String(),
				Amount:           500,
				Currency:         "KES",
				PaymentMethod:    "mpesa",
				PaymentStatus:    "completed",
				PhoneNumber:      "+254712345678",
				Reference:        "REF001",
				MpesaReceipt:     "LHD21AS9D2",
				Description:      "Internet package - Starter Plan",
				Metadata:         &metadata,
				Provider:         "mpesa",
				ProviderResponse: &providerResponse,
				CreatedAt:        now.Add(-72 * time.Hour),
				UpdatedAt:        now.Add(-72 * time.Hour),
			},
			{
				ID:            uuid.New(),
				ClientID:      clients[0].ID,
				UserID:        nil,
			CheckoutID:    uuid.New().String(),
			Amount:        1500,
			Currency:      "KES",
			PaymentMethod: "mpesa",
			PaymentStatus: "completed",
			PhoneNumber:   "+254798765432",
			Reference:     "REF002",
			MpesaReceipt:  "LHD21AS9D3",
			Description:   "Internet package - Professional Plan",
			Metadata:      &metadata,
			Provider:      "mpesa",
			CreatedAt:     now.Add(-48 * time.Hour),
			UpdatedAt:     now.Add(-48 * time.Hour),
		},
		{
			ID:            uuid.New(),
			ClientID:      clients[1].ID,
				UserID:        nil,
			CheckoutID:    uuid.New().String(),
			Amount:        450,
			Currency:      "KES",
			PaymentMethod: "mpesa",
			PaymentStatus: "pending",
			PhoneNumber:   "+254712111111",
			Reference:     "REF003",
			Description:   "Internet package - Basic Package",
			Metadata:      &metadata,
			Provider:      "mpesa",
			CreatedAt:     now,
			UpdatedAt:     now,
		},
		{
			ID:            uuid.New(),
			ClientID:      clients[0].ID,
				UserID:        nil,
			CheckoutID:    uuid.New().String(),
			Amount:        5000,
			Currency:      "KES",
			PaymentMethod: "mpesa",
			PaymentStatus: "completed",
			PhoneNumber:   "+254712345678",
			Reference:     "REF004",
			MpesaReceipt:  "LHD21AS9D4",
			Description:   "Internet package - Enterprise Plan",
			Metadata:      &metadata,
			Provider:      "mpesa",
			CreatedAt:     now.Add(-24 * time.Hour),
			UpdatedAt:     now.Add(-24 * time.Hour),
		},
		}
	}

	if err := db.CreateInBatches(transactions, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d transactions (with %d having users attached)\n", len(transactions), func() int {
		count := 0
		for _, tx := range transactions {
			if tx.UserID != nil {
				count++
			}
		}
		return count
	}())
	return nil
}

// seedAccessTokens creates sample M-Pesa access token records
func seedAccessTokens(db *gorm.DB) error {
	var count int64
	db.Model(&models.MpesaAccessToken{}).Count(&count)

	// Skip if access tokens already exist
	if count > 0 {
		fmt.Println("⊘ M-Pesa access tokens already exist, skipping...")
		return nil
	}

	var clients []models.Client
	if err := db.Find(&clients).Error; err != nil {
		return fmt.Errorf("failed to fetch clients: %w", err)
	}

	if len(clients) == 0 {
		return fmt.Errorf("no clients found to seed access tokens")
	}

	now := time.Now()
	tokens := []models.MpesaAccessToken{
		{
			ID:        uuid.New(),
			ClientID:  clients[0].ID,
			Token:     "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
			ExpiresAt: now.Add(24 * time.Hour),
			CreatedAt: now,
		},
		{
			ID:        uuid.New(),
			ClientID:  clients[1].ID,
			Token:     "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5ODc2NTQzMjEwIiwibmFtZSI6IkphbmUgU21pdGgiLCJpYXQiOjE1MTYyMzkwMjJ9.Vc1yVgwpVDrJI9xH0qZJ2KzN7M8Z1w2V3Q4L5R6S7t8",
			ExpiresAt: now.Add(24 * time.Hour),
			CreatedAt: now,
		},
	}

	if err := db.CreateInBatches(tokens, 100).Error; err != nil {
		return err
	}

	fmt.Printf("✓ Seeded %d M-Pesa access tokens\n", len(tokens))
	return nil
}
