package service




import (
    "context"
    "errors"
    "time"

    "git.gocasts.ir/ebhomengo/niki/campaign/entity"
    "git.gocasts.ir/ebhomengo/niki/repository"
    richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
    "git.gocasts.ir/ebhomengo/niki/types"
)




type CampaignService struct {
    repo           repository.CampaignRepository
    participantRepo repository.CampaignParticipantRepository
}


type CampaignServiceInterface interface {
    CreateCampaign(ctx context.Context, req CampaignRepository) (types.ID, error)
}

// NewCampaignService creates a new campaign service
func NewCampaignService(
    repo repository.CampaignRepository,
    participantRepo repository.CampaignParticipantRepository,
) *CampaignService {
    return &CampaignService{
        repo:           repo,
        participantRepo: participantRepo,
    }
}


// CreateCampaign creates a new campaign
func (s *CampaignService) CreateCampaign(ctx context.Context, req CreateCampaignRequest) (types.ID, error) {
    const Op = "service.campaign.create_campaign"

    // Business Logic: Validation
    if req.Title == "" {
        return 0, richerror.New(Op).WithErr(errors.New("title is required"))
    }

    if req.GoalAmount <= 0 {
        return 0, richerror.New(Op).WithErr(errors.New("goal_amount must be greater than 0"))
    }

    if req.AdminID == 0 {
        return 0, richerror.New(Op).WithErr(errors.New("admin_id is required"))
    }

    // Business Logic: Validate status
    validStatuses := map[string]bool{
        "draft":     true,
        "active":    true,
        "completed": true,
        "cancelled": true,
    }

    if !validStatuses[req.Status] {
        return 0, richerror.New(Op).WithErr(errors.New("invalid status"))
    }


    // Create campaign entity
    campaign := entity.Campaign{
        Title:        req.Title,
        Description:  req.Description,
        GoalAmount:   req.GoalAmount,
        RaisedAmount: 0, // Initially 0
        Status:       entity.CampaignStatus(req.Status),
        DeadlineAt:   req.DeadlineAt,
        AdminID:      req.AdminID,
        CreatedAt:    time.Now(),
    }

    // Call repository
    campaignID, err := s.repo.CreateCampaign(ctx, campaign)
    if err != nil {
        return 0, richerror.New(Op).WithErr(err)
    }

    return campaignID, nil
}
