package services

import (
	"context"

	"github.com/google/uuid"
	"backend/internal/models"
	"backend/internal/repository"
)

type InternetPackageService struct {
	repo *repository.InternetPackageRepository
}

func NewInternetPackageService(repo *repository.InternetPackageRepository) *InternetPackageService {
	return &InternetPackageService{
		repo: repo,
	}
}

// CreatePackage creates a new internet package
func (s *InternetPackageService) CreatePackage(ctx context.Context, clientID string, req *models.CreateInternetPackageRequest) (*models.InternetPackageResponse, error) {
	// Set defaults
	currency := "KES"
	if req.Currency != nil {
		currency = *req.Currency
	}

	burstEnabled := false
	if req.BurstEnabled != nil {
		burstEnabled = *req.BurstEnabled
	}

	scheduleEnabled := false
	if req.ScheduleEnabled != nil {
		scheduleEnabled = *req.ScheduleEnabled
	}

	hiddenFromClient := false
	if req.HiddenFromClient != nil {
		hiddenFromClient = *req.HiddenFromClient
	}

	isActive := true
	if req.IsActive != nil {
		isActive = *req.IsActive
	}

	pkg := &models.InternetPackage{
		ID:                uuid.New(),
		ClientID:          clientID,
		PackageType:       req.PackageType,
		Name:              req.Name,
		Description:       req.Description,
		Duration:          req.Duration,
		DurationMinutes:   req.DurationMinutes,
		UploadSpeed:       req.UploadSpeed,
		DownloadSpeed:     req.DownloadSpeed,
		Speed:             req.Speed,
		Amount:            req.Amount,
		Currency:          currency,
		Devices:           req.Devices,
		TotalLimit:        req.TotalLimit,
		BurstEnabled:      burstEnabled,
		BurstLimit:        req.BurstLimit,
		BurstThreshold:    req.BurstThreshold,
		BurstTime:         req.BurstTime,
		ScheduleEnabled:   scheduleEnabled,
		ScheduleStartTime: req.ScheduleStartTime,
		ScheduleEndTime:   req.ScheduleEndTime,
		AvailableDays:     req.AvailableDays,
		HiddenFromClient:  hiddenFromClient,
		Features:          req.Features,
		Category:          req.Category,
		Popular:           req.Popular,
		IsActive:          isActive,
	}

	if err := s.repo.Create(ctx, pkg); err != nil {
		return nil, err
	}

	return s.toResponse(pkg), nil
}

// GetPackage retrieves a package by ID
func (s *InternetPackageService) GetPackage(ctx context.Context, id uuid.UUID, clientID string) (*models.InternetPackageResponse, error) {
	pkg, err := s.repo.FindByID(ctx, id, clientID)
	if err != nil {
		return nil, err
	}

	return s.toResponse(pkg), nil
}

// GetAllPackages retrieves all packages for a client
func (s *InternetPackageService) GetAllPackages(ctx context.Context, clientID string, activeOnly bool, packageType *string, searchQuery *string, limit, offset int) ([]*models.InternetPackageResponse, int, error) {
	packages, err := s.repo.FindAll(ctx, clientID, activeOnly, packageType, searchQuery, limit, offset)
	if err != nil {
		return nil, 0, err
	}

	totalCount, err := s.repo.Count(ctx, clientID, activeOnly, packageType, searchQuery)
	if err != nil {
		return nil, 0, err
	}

	responses := make([]*models.InternetPackageResponse, len(packages))
	for i, pkg := range packages {
		responses[i] = s.toResponse(pkg)
	}

	return responses, totalCount, nil
}

// UpdatePackage updates an existing package
func (s *InternetPackageService) UpdatePackage(ctx context.Context, id uuid.UUID, clientID string, req *models.UpdateInternetPackageRequest) (*models.InternetPackageResponse, error) {
	// Get existing package
	existing, err := s.repo.FindByID(ctx, id, clientID)
	if err != nil {
		return nil, err
	}

	// Update fields if provided
	if req.PackageType != nil {
		existing.PackageType = *req.PackageType
	}
	if req.Name != nil {
		existing.Name = *req.Name
	}
	if req.Description != nil {
		existing.Description = req.Description
	}
	if req.Duration != nil {
		existing.Duration = req.Duration
	}
	if req.DurationMinutes != nil {
		existing.DurationMinutes = req.DurationMinutes
	}
	if req.UploadSpeed != nil {
		existing.UploadSpeed = req.UploadSpeed
	}
	if req.DownloadSpeed != nil {
		existing.DownloadSpeed = req.DownloadSpeed
	}
	if req.Speed != nil {
		existing.Speed = req.Speed
	}
	if req.Amount != nil {
		existing.Amount = *req.Amount
	}
	if req.Currency != nil {
		existing.Currency = *req.Currency
	}
	if req.Devices != nil {
		existing.Devices = req.Devices
	}
	if req.TotalLimit != nil {
		existing.TotalLimit = req.TotalLimit
	}
	if req.BurstEnabled != nil {
		existing.BurstEnabled = *req.BurstEnabled
	}
	if req.BurstLimit != nil {
		existing.BurstLimit = req.BurstLimit
	}
	if req.BurstThreshold != nil {
		existing.BurstThreshold = req.BurstThreshold
	}
	if req.BurstTime != nil {
		existing.BurstTime = req.BurstTime
	}
	if req.ScheduleEnabled != nil {
		existing.ScheduleEnabled = *req.ScheduleEnabled
	}
	if req.ScheduleStartTime != nil {
		existing.ScheduleStartTime = req.ScheduleStartTime
	}
	if req.ScheduleEndTime != nil {
		existing.ScheduleEndTime = req.ScheduleEndTime
	}
	if req.AvailableDays != nil {
		existing.AvailableDays = req.AvailableDays
	}
	if req.HiddenFromClient != nil {
		existing.HiddenFromClient = *req.HiddenFromClient
	}
	if req.Features != nil {
		existing.Features = req.Features
	}
	if req.Category != nil {
		existing.Category = req.Category
	}
	if req.Popular != nil {
		existing.Popular = req.Popular
	}
	if req.IsActive != nil {
		existing.IsActive = *req.IsActive
	}

	if err := s.repo.Update(ctx, existing); err != nil {
		return nil, err
	}

	return s.toResponse(existing), nil
}

// DeletePackage deletes a package
func (s *InternetPackageService) DeletePackage(ctx context.Context, id uuid.UUID, clientID string) error {
	// Verify package exists and belongs to client
	_, err := s.repo.FindByID(ctx, id, clientID)
	if err != nil {
		return err
	}

	return s.repo.Delete(ctx, id, clientID)
}

// toResponse converts InternetPackage to InternetPackageResponse
func (s *InternetPackageService) toResponse(pkg *models.InternetPackage) *models.InternetPackageResponse {
	return &models.InternetPackageResponse{
		ID:                pkg.ID,
		ClientID:          pkg.ClientID,
		PackageType:       pkg.PackageType,
		Name:              pkg.Name,
		Description:       pkg.Description,
		Duration:          pkg.Duration,
		DurationMinutes:   pkg.DurationMinutes,
		UploadSpeed:       pkg.UploadSpeed,
		DownloadSpeed:     pkg.DownloadSpeed,
		Speed:             pkg.Speed,
		Amount:            pkg.Amount,
		Currency:          pkg.Currency,
		Devices:           pkg.Devices,
		TotalLimit:        pkg.TotalLimit,
		BurstEnabled:      pkg.BurstEnabled,
		BurstLimit:        pkg.BurstLimit,
		BurstThreshold:    pkg.BurstThreshold,
		BurstTime:         pkg.BurstTime,
		ScheduleEnabled:   pkg.ScheduleEnabled,
		ScheduleStartTime: pkg.ScheduleStartTime,
		ScheduleEndTime:   pkg.ScheduleEndTime,
		AvailableDays:     pkg.AvailableDays,
		HiddenFromClient:  pkg.HiddenFromClient,
		Features:          pkg.Features,
		Category:          pkg.Category,
		Popular:           pkg.Popular,
		IsActive:          pkg.IsActive,
		CreatedAt:         pkg.CreatedAt,
		UpdatedAt:         pkg.UpdatedAt,
	}
}

