package cloudflare

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

// zone represents a Cloudflare zone (minimal fields).
type zone struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// GetZoneID resolves the Cloudflare zone ID for a domain.
// It tries the exact domain first, then strips subdomains progressively.
func (c *Client) GetZoneID(ctx context.Context, domain string) (string, error) {
	if c.debug {
		c.logger.Printf("[DEBUG] [cloudflare] GetZoneID: looking up zone for domain %q", domain)
	}

	// Try exact domain first (e.g., "demo-felhom.eu")
	if c.debug {
		c.logger.Printf("[DEBUG] [cloudflare] GetZoneID: trying exact domain %q", domain)
	}
	id, err := c.lookupZone(ctx, domain)
	if err != nil {
		return "", err
	}
	if id != "" {
		return id, nil
	}

	// Try parent domains (e.g., "felhom.eu" from "demo.felhom.eu")
	for i := 0; i < len(domain); i++ {
		if domain[i] == '.' {
			parent := domain[i+1:]
			if parent == "" {
				break
			}
			if c.debug {
				c.logger.Printf("[DEBUG] [cloudflare] GetZoneID: trying parent domain %q", parent)
			}
			id, err = c.lookupZone(ctx, parent)
			if err != nil {
				return "", err
			}
			if id != "" {
				return id, nil
			}
		}
	}

	c.logger.Printf("[WARN] [cloudflare] No zone found for domain %s", domain)
	return "", fmt.Errorf("no Cloudflare zone found for domain %q", domain)
}

// lookupZone queries the CF API for a zone by name.
func (c *Client) lookupZone(ctx context.Context, name string) (string, error) {
	path := "/zones?name=" + url.QueryEscape(name) + "&status=active"
	resp, err := c.do(ctx, "GET", path, nil)
	if err != nil {
		return "", fmt.Errorf("lookup zone %q: %w", name, err)
	}

	var zones []zone
	if err := json.Unmarshal(resp.Result, &zones); err != nil {
		return "", fmt.Errorf("decode zones: %w", err)
	}

	if len(zones) == 0 {
		return "", nil
	}

	c.logger.Printf("[INFO] [cloudflare] Resolved zone %q → %s", name, zones[0].ID)
	return zones[0].ID, nil
}
