package cloudflare

import (
	"context"
	"errors"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/cloudflare/cloudflare-go"
)

type Cloudflare struct {
	Zone  string `json:"zone" yaml:"zone"`
	Token string `json:"token" yaml:"token"`
	Email string `json:"email" yaml:"email"`
}

type DnsProvider struct {
	Api          *cloudflare.API
	TTL          int
	ZoneResource *cloudflare.ResourceContainer
	Cloudflare
}

func New(ttl int, conf Cloudflare, Http *http.Client) (*DnsProvider, error) {
	var p = DnsProvider{
		TTL:        ttl,
		Cloudflare: conf,
	}

	if p.Zone == "" || p.Email == "" || p.Token == "" {
		return nil, errors.New("cloudflare config error")
	}

	p.ZoneResource = cloudflare.ZoneIdentifier(p.Zone)
	var err error
	p.Api, err = cloudflare.New(p.Cloudflare.Token, p.Cloudflare.Email)
	return &p, err
}

func (a DnsProvider) SetDomainRecord(domain, ip string) error {
	rc := cloudflare.ResourceContainer{Identifier: a.Cloudflare.Zone}
	dnsRecords, resultInfo, err := a.Api.ListDNSRecords(
		context.TODO(),
		&rc,
		cloudflare.ListDNSRecordsParams{
			Name: domain,
		},
	)
	if err != nil {
		return err
	}

	if resultInfo.Count == 0 {
		log.Println("not found record for domain:", domain)
		return errors.New("not found record for domain:" + domain)
	}

	log.Println("found record(s) for domain:", domain)
	for _, record := range dnsRecords {
		fmt.Println(record.ID, record.Name, record.Content)
	}

	// update record
	record := dnsRecords[0]
	comment := fmt.Sprintf("updates on %s by BitSrunLoginGo", time.Now().Format("2006-01-02 15:04:05"))
	record, err = a.Api.UpdateDNSRecord(context.TODO(), &rc, cloudflare.UpdateDNSRecordParams{
		ID:      record.ID,
		Name:    record.Name,
		Type:    record.Type,
		Content: ip,
		TTL:     record.TTL,
		Proxied: record.Proxied,
		Comment: &comment,
	})

	if err != nil {
		return err
	}
	fmt.Println("update record success:", record.ID, record.Name, record.Content)
	return nil
}
