package service

import (
	"context"
	"fmt"
	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
	"github.com/spf13/cast"
	"github.com/spf13/viper"
)

type RequiredService interface {
	Required(ctx context.Context) (string, error)
	SendForm(ctx context.Context, addTokenUrl string, addSendUrl string, formData map[string]interface{}) ([]byte, error)
	GetKeyAndField(ctx context.Context, keyName string, fieldName string) (*v1.KeyAndFieldResponse, error)
}

func NewRequiredService(
	service *Service,
	crawler CrawlerService,
	conf *viper.Viper,
) RequiredService {
	return &requiredService{
		Service: service,
		crawler: crawler,
		url:     conf.GetString("crawler.Url"),
	}
}

type requiredService struct {
	*Service
	crawler CrawlerService
	url     string
}

func (s *requiredService) Required(ctx context.Context) (string, error) {

	//if req.Uid == 0 {
	//	return nil, fmt.Errorf("uid is required")
	//}
	//res.ExpiredAt, err = service.duedate.NextDueDate(ctx, req.Uid, req.HostId)
	//if err != nil {
	//	return nil, err
	//}
	res, err := s.crawler.GetLoginCookie(ctx)
	if err != nil {
		return "", err
	}
	return res, nil
}

func (s *requiredService) SendForm(ctx context.Context, addTokenUrl string, addSendUrl string, formData map[string]interface{}) ([]byte, error) {
	cookie, err := s.Required(ctx)
	if err != nil {
		return nil, err
	}
	tokenUrl := s.url + addTokenUrl
	tokens, err := s.crawler.GetFormTokens(ctx, tokenUrl, cookie)
	if err != nil {
		return nil, err
	}
	formData["__go_admin_previous_"] = tokens["previous"]
	formData["__go_admin_t_"] = tokens["t"]
	sendUrl := s.url + addSendUrl
	res, err := s.crawler.SendFormData(ctx, sendUrl, cookie, formData)
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (s *requiredService) GetKeyAndField(ctx context.Context, keyName string, fieldName string) (*v1.KeyAndFieldResponse, error) {
	var res v1.KeyAndFieldResponse
	var err error
	res.Key, err = s.crawler.GetKey(ctx, keyName)
	if err != nil {
		return nil, err
	}
	field, err := s.crawler.GetField(ctx, keyName)
	if err != nil {
		return nil, err
	}
	res.FieldId = cast.ToInt(field[fieldName])
	if res.FieldId == 0 {
		return nil, fmt.Errorf(keyName + " not found")
	}
	return &res, nil
}
