package domain

import (
	"time"
)

type DurationUnit string

const (
	DurationUnitDay   DurationUnit = "DAY"
	DurationUnitWeek  DurationUnit = "WEEK"
	DurationUnitMonth DurationUnit = "MONTH"
	DurationUnitYear  DurationUnit = "YEAR"
)

type SubscriptionStatus string

const (
	SubscriptionStatusPending   SubscriptionStatus = "PENDING"
	SubscriptionStatusActive    SubscriptionStatus = "ACTIVE"
	SubscriptionStatusExpired   SubscriptionStatus = "EXPIRED"
	SubscriptionStatusCancelled SubscriptionStatus = "CANCELLED"
)

type SubscriptionPlan struct {
	ID            int64
	Name          string
	Description   *string
	DurationValue int32
	DurationUnit  string
	Price         float64
	Currency      string
	IsActive      bool
	CreatedAt     time.Time
	UpdatedAt     *time.Time
}

type UserSubscription struct {
	ID               int64
	UserID           int64
	PlanID           int64
	StartsAt         time.Time
	ExpiresAt        time.Time
	Status           string
	PaymentReference *string
	PaymentMethod    *string
	AutoRenew        bool
	CancelledAt      *time.Time
	CreatedAt        time.Time
	UpdatedAt        *time.Time
	// Joined fields from plan
	PlanName      *string
	DurationValue *int32
	DurationUnit  *string
	Price         *float64
	Currency      *string
}

type CreateSubscriptionPlanInput struct {
	Name          string
	Description   *string
	DurationValue int32
	DurationUnit  string
	Price         float64
	Currency      string
	IsActive      *bool
}

type UpdateSubscriptionPlanInput struct {
	Name          *string
	Description   *string
	DurationValue *int32
	DurationUnit  *string
	Price         *float64
	Currency      *string
	IsActive      *bool
}

type CreateUserSubscriptionInput struct {
	UserID           int64
	PlanID           int64
	StartsAt         *time.Time
	ExpiresAt        time.Time
	Status           *string
	PaymentReference *string
	PaymentMethod    *string
	AutoRenew        *bool
}

// CalculateExpiryDate calculates the expiry date based on plan duration
func CalculateExpiryDate(startTime time.Time, durationValue int32, durationUnit string) time.Time {
	switch durationUnit {
	case string(DurationUnitDay):
		return startTime.AddDate(0, 0, int(durationValue))
	case string(DurationUnitWeek):
		return startTime.AddDate(0, 0, int(durationValue)*7)
	case string(DurationUnitMonth):
		return startTime.AddDate(0, int(durationValue), 0)
	case string(DurationUnitYear):
		return startTime.AddDate(int(durationValue), 0, 0)
	default:
		return startTime.AddDate(0, int(durationValue), 0) // Default to months
	}
}
