package businessapi

import (
	"context"
	"net/url"

	"git.warky.dev/wdevs/whatshooked/pkg/events"
	"git.warky.dev/wdevs/whatshooked/pkg/logging"

	"go.mau.fi/whatsmeow/types"
)

// ListCatalogs returns all product catalogs linked to the business account.
func (c *Client) ListCatalogs(ctx context.Context) (*CatalogListResponse, error) {
	wabaID, err := c.resolveWABAID(ctx)
	if err != nil {
		return nil, err
	}

	params := url.Values{
		"fields": {"id,name,product_count"},
	}

	var resp CatalogListResponse
	if err := c.graphAPIGet(ctx, wabaID+"/product_catalogs", params, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ListProducts returns products in a specific catalog.
func (c *Client) ListProducts(ctx context.Context, catalogID string) (*ProductListResponse, error) {
	params := url.Values{
		"fields": {"product_retailer_id,name,description,image_url,base_price,currency,availability,category"},
	}

	var resp ProductListResponse
	if err := c.graphAPIGet(ctx, catalogID+"/products", params, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// SendCatalogMessage sends a catalog message that shares the full product catalog.
// thumbnailProductRetailerID is optional — when non-empty it sets which product image
// appears as the catalog preview thumbnail.
func (c *Client) SendCatalogMessage(ctx context.Context, jid types.JID, bodyText string, thumbnailProductRetailerID string) (string, error) {
	if ctx == nil {
		ctx = context.Background()
	}
	phoneNumber := jidToPhoneNumber(jid)

	action := map[string]any{
		"name": "catalog_message",
	}
	if thumbnailProductRetailerID != "" {
		action["parameters"] = map[string]any{
			"thumbnail_product_retailer_id": thumbnailProductRetailerID,
		}
	}

	msg := map[string]any{
		"messaging_product": "whatsapp",
		"to":                phoneNumber,
		"type":              "interactive",
		"interactive": map[string]any{
			"type":   "catalog_message",
			"body":   map[string]any{"text": bodyText},
			"action": action,
		},
	}

	messageID, err := c.postToMessagesEndpoint(ctx, msg)
	if err != nil {
		c.eventBus.Publish(events.MessageFailedEvent(ctx, c.id, phoneNumber, bodyText, err))
		return "", err
	}

	logging.Debug("Catalog message sent via Business API", "account_id", c.id, "to", phoneNumber)
	c.eventBus.Publish(events.MessageSentEvent(ctx, c.id, messageID, phoneNumber, bodyText))
	return messageID, nil
}

// SendSingleProduct sends a single-product interactive message.
func (c *Client) SendSingleProduct(ctx context.Context, jid types.JID, catalogID, productRetailerID, bodyText, footerText string) (string, error) {
	if ctx == nil {
		ctx = context.Background()
	}
	phoneNumber := jidToPhoneNumber(jid)

	interactive := map[string]any{
		"type": "product",
		"header": map[string]any{
			"type":                "product",
			"product_retailer_id": productRetailerID,
		},
		"body": map[string]any{"text": bodyText},
		"action": map[string]any{
			"catalog_id":          catalogID,
			"product_retailer_id": productRetailerID,
		},
	}
	if footerText != "" {
		interactive["footer"] = map[string]any{"text": footerText}
	}

	msg := map[string]any{
		"messaging_product": "whatsapp",
		"to":                phoneNumber,
		"type":              "interactive",
		"interactive":       interactive,
	}

	messageID, err := c.postToMessagesEndpoint(ctx, msg)
	if err != nil {
		c.eventBus.Publish(events.MessageFailedEvent(ctx, c.id, phoneNumber, bodyText, err))
		return "", err
	}

	logging.Debug("Single product sent via Business API", "account_id", c.id, "to", phoneNumber, "product", productRetailerID)
	c.eventBus.Publish(events.MessageSentEvent(ctx, c.id, messageID, phoneNumber, bodyText))
	return messageID, nil
}

// SendProductList sends a multi-product list message. Up to 30 products across up to 10 sections.
func (c *Client) SendProductList(ctx context.Context, jid types.JID, headerText, bodyText, footerText, catalogID string, sections []ProductListSection) (string, error) {
	if ctx == nil {
		ctx = context.Background()
	}
	phoneNumber := jidToPhoneNumber(jid)

	actionSections := make([]map[string]any, len(sections))
	for i, s := range sections {
		items := make([]map[string]any, len(s.ProductItems))
		for j, item := range s.ProductItems {
			items[j] = map[string]any{"product_retailer_id": item.ProductRetailerID}
		}
		actionSections[i] = map[string]any{
			"title":         s.Title,
			"product_items": items,
		}
	}

	interactive := map[string]any{
		"type":   "product_list",
		"header": map[string]any{"type": "text", "text": headerText},
		"body":   map[string]any{"text": bodyText},
		"action": map[string]any{
			"catalog_id": catalogID,
			"sections":   actionSections,
		},
	}
	if footerText != "" {
		interactive["footer"] = map[string]any{"text": footerText}
	}

	msg := map[string]any{
		"messaging_product": "whatsapp",
		"to":                phoneNumber,
		"type":              "interactive",
		"interactive":       interactive,
	}

	messageID, err := c.postToMessagesEndpoint(ctx, msg)
	if err != nil {
		c.eventBus.Publish(events.MessageFailedEvent(ctx, c.id, phoneNumber, bodyText, err))
		return "", err
	}

	logging.Debug("Product list sent via Business API", "account_id", c.id, "to", phoneNumber, "sections", len(sections))
	c.eventBus.Publish(events.MessageSentEvent(ctx, c.id, messageID, phoneNumber, bodyText))
	return messageID, nil
}
