package services

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

type CPanelConfig struct {
	Host     string `json:"host"`
	Username string `json:"username"`
	APIToken string `json:"apiToken"`
}

type CPanelService struct {
	credentials *CredentialsService
}

func NewCPanelService(c *CredentialsService) *CPanelService {
	return &CPanelService{credentials: c}
}

// GetConfig returns the decrypted cPanel configuration
func (s *CPanelService) GetConfig(ctx context.Context) (*CPanelConfig, error) {
	payload, err := s.credentials.GetDecryptedKey(ctx, "cpanel")
	if err != nil {
		return nil, fmt.Errorf("cpanel credentials missing: %w", err)
	}

	var cfg CPanelConfig
	if err := json.Unmarshal([]byte(payload), &cfg); err != nil {
		return nil, fmt.Errorf("invalid cpanel config: %w", err)
	}

	if cfg.Host == "" || cfg.Username == "" || cfg.APIToken == "" {
		return nil, fmt.Errorf("cpanel not configured")
	}

	return &cfg, nil
}

// Example method: ListEmailAccounts (using API Token authentication)
func (s *CPanelService) ListEmailAccounts(ctx context.Context) (map[string]interface{}, error) {
	cfg, err := s.GetConfig(ctx)
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("%s/execute/Email/list_pops", cfg.Host)
	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return nil, err
	}

	// cPanel Token Auth Header: Authorization: cpanel <username>:<token>
	req.Header.Set("Authorization", fmt.Sprintf("cpanel %s:%s", cfg.Username, cfg.APIToken))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("cpanel api returned %d", resp.StatusCode)
	}

	var result map[string]interface{}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, err
	}

	return result, nil
}
