package models

import (
	"time"

	"github.com/google/uuid"
)

// SubscriptionStatus represents the status of a subscription
type SubscriptionStatus string

const (
	StatusTrialing SubscriptionStatus = "trialing"
	StatusActive   SubscriptionStatus = "active"
	StatusPastDue  SubscriptionStatus = "past_due"
	StatusCanceled SubscriptionStatus = "canceled"
	StatusExpired  SubscriptionStatus = "expired"
)

// PlanID represents the available plan IDs
type PlanID string

const (
	PlanBasic    PlanID = "basic"
	PlanStandard PlanID = "standard"
	PlanPremium  PlanID = "premium"
)

// TaskType represents the type of task
type TaskType string

const (
	TaskTypeCorrection TaskType = "correction"
	TaskTypeLetter     TaskType = "letter"
	TaskTypeMeeting    TaskType = "meeting"
	TaskTypeBatch      TaskType = "batch"
	TaskTypeOther      TaskType = "other"
)

// CarryoverMonthsCap is the maximum number of months tasks can accumulate
const CarryoverMonthsCap = 5

// Subscription represents a user's subscription
type Subscription struct {
	ID                   uuid.UUID          `json:"id"`
	UserID               uuid.UUID          `json:"user_id"`
	StripeCustomerID     string             `json:"stripe_customer_id"`
	StripeSubscriptionID string             `json:"stripe_subscription_id"`
	PlanID               PlanID             `json:"plan_id"`
	Status               SubscriptionStatus `json:"status"`
	TrialEnd             *time.Time         `json:"trial_end,omitempty"`
	CurrentPeriodEnd     *time.Time         `json:"current_period_end,omitempty"`
	CancelAtPeriodEnd    bool               `json:"cancel_at_period_end"`
	CreatedAt            time.Time          `json:"created_at"`
	UpdatedAt            time.Time          `json:"updated_at"`
}

// BillingPlan represents a billing plan with its features and limits
type BillingPlan struct {
	ID            PlanID       `json:"id"`
	StripePriceID string       `json:"stripe_price_id"`
	Name          string       `json:"name"`
	Description   string       `json:"description"`
	PriceCents    int          `json:"price_cents"` // Price in cents (990 = 9.90 EUR)
	Currency      string       `json:"currency"`
	Interval      string       `json:"interval"` // "month" or "year"
	Features      PlanFeatures `json:"features"`
	IsActive      bool         `json:"is_active"`
	SortOrder     int          `json:"sort_order"`
}

// PlanFeatures represents the features and limits of a plan
type PlanFeatures struct {
	// Task-based limits (primary billing unit)
	MonthlyTaskAllowance int `json:"monthly_task_allowance"` // Tasks per month
	MaxTaskBalance       int `json:"max_task_balance"`       // Max accumulated tasks (allowance * CarryoverMonthsCap)

	// Legacy fields for backward compatibility (deprecated, use task-based limits)
	AIRequestsLimit int `json:"ai_requests_limit,omitempty"`
	DocumentsLimit  int `json:"documents_limit,omitempty"`

	// Feature flags
	FeatureFlags    []string `json:"feature_flags"`
	MaxTeamMembers  int      `json:"max_team_members,omitempty"`
	PrioritySupport bool     `json:"priority_support"`
	CustomBranding  bool     `json:"custom_branding"`
	BatchProcessing bool     `json:"batch_processing"`
	CustomTemplates bool     `json:"custom_templates"`

	// Premium: Fair Use (no visible limit)
	FairUseMode bool `json:"fair_use_mode"`
}

// Task represents a single task that consumes 1 unit from the balance
type Task struct {
	ID        uuid.UUID `json:"id"`
	AccountID uuid.UUID `json:"account_id"`
	TaskType  TaskType  `json:"task_type"`
	CreatedAt time.Time `json:"created_at"`
	Consumed  bool      `json:"consumed"` // Always true when created
	// Internal metrics (not shown to user)
	PageCount   int `json:"-"`
	TokenCount  int `json:"-"`
	ProcessTime int `json:"-"` // in seconds
}

// AccountUsage represents the task-based usage for an account
type AccountUsage struct {
	ID                   uuid.UUID  `json:"id"`
	AccountID            uuid.UUID  `json:"account_id"`
	PlanID               PlanID     `json:"plan"`
	MonthlyTaskAllowance int        `json:"monthly_task_allowance"`
	CarryoverMonthsCap   int        `json:"carryover_months_cap"` // Always 5
	MaxTaskBalance       int        `json:"max_task_balance"`     // allowance * cap
	TaskBalance          int        `json:"task_balance"`         // Current available tasks
	LastRenewalAt        time.Time  `json:"last_renewal_at"`
	CreatedAt            time.Time  `json:"created_at"`
	UpdatedAt            time.Time  `json:"updated_at"`
}

// UsageSummary tracks usage for a specific period (internal metrics)
type UsageSummary struct {
	ID          uuid.UUID `json:"id"`
	UserID      uuid.UUID `json:"user_id"`
	UsageType   string    `json:"usage_type"` // "task", "page", "token"
	PeriodStart time.Time `json:"period_start"`
	TotalCount  int       `json:"total_count"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

// UserEntitlements represents cached entitlements for a user
type UserEntitlements struct {
	ID          uuid.UUID    `json:"id"`
	UserID      uuid.UUID    `json:"user_id"`
	PlanID      PlanID       `json:"plan_id"`
	TaskBalance int          `json:"task_balance"`
	MaxBalance  int          `json:"max_balance"`
	Features    PlanFeatures `json:"features"`
	UpdatedAt   time.Time    `json:"updated_at"`
	// Legacy fields for backward compatibility with old entitlement service
	AIRequestsLimit int `json:"ai_requests_limit"`
	AIRequestsUsed  int `json:"ai_requests_used"`
	DocumentsLimit  int `json:"documents_limit"`
	DocumentsUsed   int `json:"documents_used"`
}

// StripeWebhookEvent tracks processed webhook events for idempotency
type StripeWebhookEvent struct {
	StripeEventID string    `json:"stripe_event_id"`
	EventType     string    `json:"event_type"`
	Processed     bool      `json:"processed"`
	ProcessedAt   time.Time `json:"processed_at"`
	CreatedAt     time.Time `json:"created_at"`
}

// BillingStatusResponse is the response for the billing status endpoint
type BillingStatusResponse struct {
	HasSubscription bool              `json:"has_subscription"`
	Subscription    *SubscriptionInfo `json:"subscription,omitempty"`
	TaskUsage       *TaskUsageInfo    `json:"task_usage,omitempty"`
	Entitlements    *EntitlementInfo  `json:"entitlements,omitempty"`
	AvailablePlans  []BillingPlan     `json:"available_plans,omitempty"`
}

// SubscriptionInfo contains subscription details for the response
type SubscriptionInfo struct {
	PlanID            PlanID             `json:"plan_id"`
	PlanName          string             `json:"plan_name"`
	Status            SubscriptionStatus `json:"status"`
	IsTrialing        bool               `json:"is_trialing"`
	TrialDaysLeft     int                `json:"trial_days_left,omitempty"`
	CurrentPeriodEnd  *time.Time         `json:"current_period_end,omitempty"`
	CancelAtPeriodEnd bool               `json:"cancel_at_period_end"`
	PriceCents        int                `json:"price_cents"`
	Currency          string             `json:"currency"`
}

// TaskUsageInfo contains current task usage information
// This is the ONLY usage info shown to users
type TaskUsageInfo struct {
	TasksAvailable int    `json:"tasks_available"` // Current balance
	MaxTasks       int    `json:"max_tasks"`       // Max possible balance
	InfoText       string `json:"info_text"`       // "Aufgaben verfuegbar: X von max. Y"
	TooltipText    string `json:"tooltip_text"`    // "Aufgaben koennen sich bis zu 5 Monate ansammeln."
}

// EntitlementInfo contains feature entitlements
type EntitlementInfo struct {
	Features        []string `json:"features"`
	MaxTeamMembers  int      `json:"max_team_members,omitempty"`
	PrioritySupport bool     `json:"priority_support"`
	CustomBranding  bool     `json:"custom_branding"`
	BatchProcessing bool     `json:"batch_processing"`
	CustomTemplates bool     `json:"custom_templates"`
	FairUseMode     bool     `json:"fair_use_mode"` // Premium only
}

// StartTrialRequest is the request to start a trial
type StartTrialRequest struct {
	PlanID PlanID `json:"plan_id" binding:"required"`
}

// StartTrialResponse is the response after starting a trial
type StartTrialResponse struct {
	CheckoutURL string `json:"checkout_url"`
	SessionID   string `json:"session_id"`
}

// ChangePlanRequest is the request to change plans
type ChangePlanRequest struct {
	NewPlanID PlanID `json:"new_plan_id" binding:"required"`
}

// ChangePlanResponse is the response after changing plans
type ChangePlanResponse struct {
	Success       bool   `json:"success"`
	Message       string `json:"message"`
	EffectiveDate string `json:"effective_date,omitempty"`
}

// CancelSubscriptionResponse is the response after canceling
type CancelSubscriptionResponse struct {
	Success     bool   `json:"success"`
	Message     string `json:"message"`
	CancelDate  string `json:"cancel_date"`
	ActiveUntil string `json:"active_until"`
}

// CustomerPortalResponse contains the portal URL
type CustomerPortalResponse struct {
	PortalURL string `json:"portal_url"`
}

// ConsumeTaskRequest is the request to consume a task (internal)
type ConsumeTaskRequest struct {
	UserID   string   `json:"user_id" binding:"required"`
	TaskType TaskType `json:"task_type" binding:"required"`
}

// ConsumeTaskResponse is the response after consuming a task
type ConsumeTaskResponse struct {
	Success        bool   `json:"success"`
	TaskID         string `json:"task_id,omitempty"`
	TasksRemaining int    `json:"tasks_remaining"`
	Message        string `json:"message,omitempty"`
}

// CheckTaskAllowedResponse is the response for task limit checks
type CheckTaskAllowedResponse struct {
	Allowed        bool   `json:"allowed"`
	TasksAvailable int    `json:"tasks_available"`
	MaxTasks       int    `json:"max_tasks"`
	PlanID         PlanID `json:"plan_id"`
	Message        string `json:"message,omitempty"`
}

// EntitlementCheckResponse is the response for entitlement checks (internal)
type EntitlementCheckResponse struct {
	HasEntitlement bool   `json:"has_entitlement"`
	PlanID         PlanID `json:"plan_id,omitempty"`
	Message        string `json:"message,omitempty"`
}

// TaskLimitError represents the error when task limit is reached
type TaskLimitError struct {
	Error          string `json:"error"`
	CurrentBalance int    `json:"current_balance"`
	Plan           PlanID `json:"plan"`
}

// UsageInfo represents current usage information (legacy, prefer TaskUsageInfo)
type UsageInfo struct {
	AIRequestsUsed    int     `json:"ai_requests_used"`
	AIRequestsLimit   int     `json:"ai_requests_limit"`
	AIRequestsPercent float64 `json:"ai_requests_percent"`
	DocumentsUsed     int     `json:"documents_used"`
	DocumentsLimit    int     `json:"documents_limit"`
	DocumentsPercent  float64 `json:"documents_percent"`
	PeriodStart       string  `json:"period_start"`
	PeriodEnd         string  `json:"period_end"`
}

// CheckUsageResponse is the response for legacy usage checks
type CheckUsageResponse struct {
	Allowed      bool   `json:"allowed"`
	CurrentUsage int    `json:"current_usage"`
	Limit        int    `json:"limit"`
	Remaining    int    `json:"remaining"`
	Message      string `json:"message,omitempty"`
}

// TrackUsageRequest is the request to track usage (internal)
type TrackUsageRequest struct {
	UserID    string `json:"user_id" binding:"required"`
	UsageType string `json:"usage_type" binding:"required"`
	Quantity  int    `json:"quantity"`
}

// GetDefaultPlans returns the default billing plans with task-based limits
func GetDefaultPlans() []BillingPlan {
	return []BillingPlan{
		{
			ID:          PlanBasic,
			Name:        "Basic",
			Description: "Perfekt fuer den Einstieg - Gelegentliche Nutzung",
			PriceCents:  990, // 9.90 EUR
			Currency:    "eur",
			Interval:    "month",
			Features: PlanFeatures{
				MonthlyTaskAllowance: 30,                       // 30 tasks/month
				MaxTaskBalance:       30 * CarryoverMonthsCap,  // 150 max
				FeatureFlags:         []string{"basic_ai", "basic_documents"},
				MaxTeamMembers:       1,
				PrioritySupport:      false,
				CustomBranding:       false,
				BatchProcessing:      false,
				CustomTemplates:      false,
				FairUseMode:          false,
			},
			IsActive:  true,
			SortOrder: 1,
		},
		{
			ID:          PlanStandard,
			Name:        "Standard",
			Description: "Fuer regelmaessige Nutzer - Mehrere Klassen und regelmaessige Korrekturen",
			PriceCents:  1990, // 19.90 EUR
			Currency:    "eur",
			Interval:    "month",
			Features: PlanFeatures{
				MonthlyTaskAllowance: 100,                      // 100 tasks/month
				MaxTaskBalance:       100 * CarryoverMonthsCap, // 500 max
				FeatureFlags:         []string{"basic_ai", "basic_documents", "templates", "batch_processing"},
				MaxTeamMembers:       3,
				PrioritySupport:      false,
				CustomBranding:       false,
				BatchProcessing:      true,
				CustomTemplates:      true,
				FairUseMode:          false,
			},
			IsActive:  true,
			SortOrder: 2,
		},
		{
			ID:          PlanPremium,
			Name:        "Premium",
			Description: "Sorglos-Tarif - Vielnutzer, Teams, schulischer Kontext",
			PriceCents:  3990, // 39.90 EUR
			Currency:    "eur",
			Interval:    "month",
			Features: PlanFeatures{
				MonthlyTaskAllowance: 1000,                      // Very high (Fair Use)
				MaxTaskBalance:       1000 * CarryoverMonthsCap, // 5000 max (not shown to user)
				FeatureFlags:         []string{"basic_ai", "basic_documents", "templates", "batch_processing", "team_features", "admin_panel", "audit_log", "api_access"},
				MaxTeamMembers:       10,
				PrioritySupport:      true,
				CustomBranding:       true,
				BatchProcessing:      true,
				CustomTemplates:      true,
				FairUseMode:          true, // No visible limit
			},
			IsActive:  true,
			SortOrder: 3,
		},
	}
}

// CalculateMaxTaskBalance calculates max task balance from monthly allowance
func CalculateMaxTaskBalance(monthlyAllowance int) int {
	return monthlyAllowance * CarryoverMonthsCap
}
