package portal

import (
	"encoding/json"
	"net/http"
)

type BillingPlan struct {
	Name           string `json:"name"`
	Price          int    `json:"price"`
	MaxDeployments int    `json:"maxDeployments"`
	MaxCPU         string `json:"maxCPU"`
	MaxMemory      string `json:"maxMemory"`
	MaxClusters    int    `json:"maxClusters"`
}

type ResourceUsage struct {
	Deployments          int     `json:"deployments"`
	DeploymentPercentage float64 `json:"deploymentPercentage"`
	CPU                  string  `json:"cpu"`
	CPUPercentage        float64 `json:"cpuPercentage"`
	Memory               string  `json:"memory"`
	MemoryPercentage     float64 `json:"memoryPercentage"`
	Clusters             int     `json:"clusters"`
	ClusterPercentage    float64 `json:"clusterPercentage"`
}

type BillingTransaction struct {
	Date        string  `json:"date"`
	Description string  `json:"description"`
	Amount      float64 `json:"amount"`
	Status      string  `json:"status"`
}

func (p *Portal) handleBilling(w http.ResponseWriter, r *http.Request) {
	// Get current customer
	customer, err := p.operator.GetCurrentCustomer(r.Context())
	if err != nil {
		http.Error(w, "Failed to get customer info", http.StatusInternalServerError)
		return
	}

	// Get resource usage
	usage, err := p.operator.GetResourceUsage(r.Context(), customer.Name)
	if err != nil {
		http.Error(w, "Failed to get resource usage", http.StatusInternalServerError)
		return
	}

	// Get billing history
	history, err := p.operator.GetBillingHistory(r.Context(), customer.Name)
	if err != nil {
		http.Error(w, "Failed to get billing history", http.StatusInternalServerError)
		return
	}

	data := struct {
		CurrentPlan    BillingPlan          `json:"currentPlan"`
		Plans          []BillingPlan        `json:"plans"`
		Usage          ResourceUsage        `json:"usage"`
		BillingHistory []BillingTransaction `json:"billingHistory"`
	}{
		CurrentPlan: BillingPlan{
			Name:           customer.Spec.BillingTier,
			Price:          getPlanPrice(customer.Spec.BillingTier),
			MaxDeployments: customer.Spec.ResourceQuota.MaxDeployments,
			MaxCPU:         customer.Spec.ResourceQuota.MaxCPU,
			MaxMemory:      customer.Spec.ResourceQuota.MaxMemory,
			MaxClusters:    customer.Spec.ResourceQuota.MaxClusters,
		},
		Plans:          getAvailablePlans(),
		Usage:          usage,
		BillingHistory: history,
	}

	if err := p.templates.ExecuteTemplate(w, "billing.html", data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func (p *Portal) handleAPIBillingPlan(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		Plan string `json:"plan"`
	}

	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request", http.StatusBadRequest)
		return
	}

	if err := p.operator.UpdateBillingPlan(r.Context(), req.Plan); err != nil {
		http.Error(w, "Failed to update plan", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}

func getAvailablePlans() []BillingPlan {
	return []BillingPlan{
		{
			Name:           "basic",
			Price:          49,
			MaxDeployments: 3,
			MaxCPU:         "2",
			MaxMemory:      "2Gi",
			MaxClusters:    1,
		},
		{
			Name:           "pro",
			Price:          149,
			MaxDeployments: 10,
			MaxCPU:         "8",
			MaxMemory:      "8Gi",
			MaxClusters:    3,
		},
		{
			Name:           "enterprise",
			Price:          499,
			MaxDeployments: 50,
			MaxCPU:         "32",
			MaxMemory:      "64Gi",
			MaxClusters:    10,
		},
	}
}

func getPlanPrice(plan string) int {
	prices := map[string]int{
		"basic":      49,
		"pro":        149,
		"enterprise": 499,
	}
	return prices[plan]
}
