package service

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

type cloudflareProvider struct {
	token  string
	client *http.Client
	zoneID string
}

func NewCloudflareProvider(apiToken string, rootDomain string) DDNSProvider {
	return &cloudflareProvider{
		token: apiToken,
		client: &http.Client{Timeout: 10 * time.Second},
		// 注意:实际场景需通过 rootDomain 获取 zoneID。此处为演示简略处理，假定初始化后能查到 zoneID
	}
}

func (p *cloudflareProvider) TestConnectivity(ctx context.Context) error {
	req, _ := http.NewRequestWithContext(ctx, "GET", "https://api.cloudflare.com/client/v4/user/tokens/verify", nil)
	req.Header.Set("Authorization", "Bearer "+p.token)
	resp, err := p.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Cloudflare 认证失败，状态码: %d", resp.StatusCode)
	}
	return nil
}

func (p *cloudflareProvider) SyncRecords(ctx context.Context, baseDomain string, records []DDNSRecord) error {
	// 实战中首先需要查询 Zones 获取 zone_id
	// 为了简化演示修复，此处假设获取 zone 的逻辑 (伪代码实现，可进一步真实拉取)
	zoneID, err := p.getZoneID(ctx, baseDomain)
	if err != nil {
		return err
	}

	for _, rec := range records {
		fullDomain := rec.Name + "." + baseDomain
		if rec.Name == "@" {
			fullDomain = baseDomain
		}

		// 1. 查询现有的 Record
		recordID, _ := p.getRecordID(ctx, zoneID, fullDomain, rec.Type)

		// 2. 构造 payload
		payload := map[string]interface{}{
			"type":    rec.Type,
			"name":    fullDomain,
			"content": rec.Value,
			"ttl":     1, // 自动
			"proxied": false,
		}
		data, _ := json.Marshal(payload)

		var req *http.Request
		if recordID != "" {
			// 更新
			req, _ = http.NewRequestWithContext(ctx, "PUT", fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records/%s", zoneID, recordID), bytes.NewReader(data))
		} else {
			// 创建
			req, _ = http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records", zoneID), bytes.NewReader(data))
		}

		req.Header.Set("Authorization", "Bearer "+p.token)
		req.Header.Set("Content-Type", "application/json")
		resp, err := p.client.Do(req)
		if err != nil {
			return err
		}
		resp.Body.Close()
	}
	return nil
}

// 辅助方法：获取 Zone ID
func (p *cloudflareProvider) getZoneID(ctx context.Context, domain string) (string, error) {
	req, _ := http.NewRequestWithContext(ctx, "GET", "https://api.cloudflare.com/client/v4/zones?name="+domain, nil)
	req.Header.Set("Authorization", "Bearer "+p.token)
	resp, err := p.client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var result struct {
		Result []struct {
			ID string `json:"id"`
		} `json:"result"`
	}
	body, _ := io.ReadAll(resp.Body)
	json.Unmarshal(body, &result)
	if len(result.Result) > 0 {
		return result.Result[0].ID, nil
	}
	return "", fmt.Errorf("找不到域名 %s 的 Zone", domain)
}

// 辅助方法：获取 Record ID
func (p *cloudflareProvider) getRecordID(ctx context.Context, zoneID, name, recType string) (string, error) {
	req, _ := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records?name=%s&type=%s", zoneID, name, recType), nil)
	req.Header.Set("Authorization", "Bearer "+p.token)
	resp, err := p.client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var result struct {
		Result []struct {
			ID string `json:"id"`
		} `json:"result"`
	}
	body, _ := io.ReadAll(resp.Body)
	json.Unmarshal(body, &result)
	if len(result.Result) > 0 {
		return result.Result[0].ID, nil
	}
	return "", nil
}
