package voucher

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"

	"git.tornberg.me/go-cart-actor/pkg/messages"
)

type Rule struct {
	Type  string `json:"type"`
	Value int64  `json:"value"`
}

type Voucher struct {
	Code        string `json:"code"`
	Value       int64  `json:"value"`
	Rules       string `json:"rules"`
	Description string `json:"description,omitempty"`
}

type Service struct {
	// Add fields here
}

var ErrInvalidCode = errors.New("invalid vouchercode")

func (s *Service) GetVoucher(code string) (*messages.AddVoucher, error) {
	if code == "" {
		return nil, ErrInvalidCode
	}
	sf, err := LoadStateFile("data/vouchers.json")
	if err != nil {
		return nil, err
	}
	v, ok := sf.GetVoucher(code)
	if !ok {
		return nil, fmt.Errorf("no voucher found for code: %s", code)
	}

	return &messages.AddVoucher{
		Code:        code,
		Value:       v.Value,
		Description: v.Description,
		VoucherRules: []string{
			v.Rules,
		},
	}, nil
}

type State struct {
	Vouchers []Voucher `json:"vouchers"`
}

type StateFile struct {
	State   State `json:"state"`
	Version int   `json:"version"`
}

func (sf *StateFile) GetVoucher(code string) (*Voucher, bool) {
	for _, v := range sf.State.Vouchers {
		if v.Code == code {
			return &v, true
		}
	}
	return nil, false
}

func LoadStateFile(fileName string) (*StateFile, error) {
	f, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	dec := json.NewDecoder(f)
	sf := &StateFile{}
	err = dec.Decode(sf)
	if err != nil {
		return nil, err
	}
	return sf, nil
}
