package handlers

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

	"git.warky.dev/wdevs/whatshooked/pkg/config"
	"git.warky.dev/wdevs/whatshooked/pkg/hooks"
	"git.warky.dev/wdevs/whatshooked/pkg/logging"
	"git.warky.dev/wdevs/whatshooked/pkg/whatsapp"
	"git.warky.dev/wdevs/whatshooked/pkg/whatsapp/businessapi"
)

// Handlers holds all HTTP handlers with their dependencies
type Handlers struct {
	whatsappMgr *whatsapp.Manager
	hookMgr     *hooks.Manager
	config      *config.Config
	configPath  string

	// Auth configuration
	authConfig *AuthConfig
}

// AuthConfig configures authentication behavior
type AuthConfig struct {
	// Validator is a custom auth validator function
	// If nil, uses built-in auth (API key, basic auth)
	Validator func(r *http.Request) bool

	// Built-in auth settings
	APIKey   string
	Username string
	Password string

	// Skip auth entirely (not recommended for production)
	Disabled bool
}

// New creates a new Handlers instance
func New(mgr *whatsapp.Manager, hookMgr *hooks.Manager, cfg *config.Config, configPath string) *Handlers {
	return &Handlers{
		whatsappMgr: mgr,
		hookMgr:     hookMgr,
		config:      cfg,
		configPath:  configPath,
		authConfig: &AuthConfig{
			APIKey:   cfg.Server.AuthKey,
			Username: cfg.Server.Username,
			Password: cfg.Server.Password,
		},
	}
}

// WithAuthConfig sets custom auth configuration
func (h *Handlers) WithAuthConfig(cfg *AuthConfig) *Handlers {
	h.authConfig = cfg
	return h
}

// getBusinessAPIClient looks up an account and asserts it is a Business API client.
// Returns a typed *businessapi.Client or an error with an appropriate message.
func (h *Handlers) getBusinessAPIClient(accountID string) (*businessapi.Client, error) {
	if accountID == "" {
		return nil, fmt.Errorf("account_id is required")
	}
	client, exists := h.whatsappMgr.GetClient(accountID)
	if !exists {
		return nil, fmt.Errorf("account %s not found", accountID)
	}
	baClient, ok := client.(*businessapi.Client)
	if !ok {
		return nil, fmt.Errorf("account %s is not a Business API account (type: %s)", accountID, client.GetType())
	}
	return baClient, nil
}

// writeJSON is a helper that writes JSON response and logs errors
func writeJSON(w http.ResponseWriter, v interface{}) {
	if err := json.NewEncoder(w).Encode(v); err != nil {
		logging.Error("Failed to encode JSON response", "error", err)
	}
}

// writeBytes is a helper that writes bytes and logs errors
func writeBytes(w http.ResponseWriter, data []byte) {
	if _, err := w.Write(data); err != nil {
		logging.Error("Failed to write response", "error", err)
	}
}
