package handlers

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

	"git.warky.dev/wdevs/whatshooked/pkg/utils"
	"git.warky.dev/wdevs/whatshooked/pkg/whatsapp/businessapi"
	"go.mau.fi/whatsmeow/types"
)

// ListTemplates returns all message templates for the account.
// POST /api/templates  {"account_id"}
func (h *Handlers) ListTemplates(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		AccountID string `json:"account_id"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	baClient, err := h.getBusinessAPIClient(req.AccountID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	resp, err := baClient.ListTemplates(r.Context())
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	writeJSON(w, resp)
}

// UploadTemplate creates a new message template.
// POST /api/templates/upload  {"account_id","name","language","category","components",[...]}
func (h *Handlers) UploadTemplate(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		AccountID string `json:"account_id"`
		businessapi.TemplateUploadRequest
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if req.Name == "" || req.Language == "" || req.Category == "" {
		http.Error(w, "name, language, and category are required", http.StatusBadRequest)
		return
	}

	baClient, err := h.getBusinessAPIClient(req.AccountID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	resp, err := baClient.UploadTemplate(r.Context(), req.TemplateUploadRequest)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	writeJSON(w, resp)
}

// DeleteTemplate deletes a template by name and language.
// POST /api/templates/delete  {"account_id","name","language"}
func (h *Handlers) DeleteTemplate(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		AccountID string `json:"account_id"`
		Name      string `json:"name"`
		Language  string `json:"language"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if req.Name == "" || req.Language == "" {
		http.Error(w, "name and language are required", http.StatusBadRequest)
		return
	}

	baClient, err := h.getBusinessAPIClient(req.AccountID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if err := baClient.DeleteTemplate(r.Context(), req.Name, req.Language); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	writeJSON(w, map[string]string{"status": "ok"})
}

// SendTemplate sends a template message.
// POST /api/send/template  {"account_id","to","template":{...}}
func (h *Handlers) SendTemplate(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		AccountID string                             `json:"account_id"`
		To        string                             `json:"to"`
		Template  *businessapi.TemplateMessageObject `json:"template"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if req.Template == nil || req.Template.Name == "" {
		http.Error(w, "template with name is required", http.StatusBadRequest)
		return
	}

	baClient, err := h.getBusinessAPIClient(req.AccountID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	jid, err := types.ParseJID(utils.FormatPhoneToJID(req.To, h.config.Server.DefaultCountryCode))
	if err != nil {
		http.Error(w, "Invalid phone number", http.StatusBadRequest)
		return
	}

	if _, err := baClient.SendTemplateMessage(r.Context(), jid, req.Template); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	writeJSON(w, map[string]string{"status": "ok"})
}
