package ingredient

import (
	"autobrew/utils"
	"fmt"
)

type IngredientType int

const (
	Base IngredientType = iota
	TopShelf
	BottomShelf
)

type Ingredient struct {
	string
	IngredientType
}

var (
	// Base
	Water   Ingredient = Ingredient{"Water", Base}
	Wine    Ingredient = Ingredient{"Wine", Base}
	Oil     Ingredient = Ingredient{"Oil", Base}
	Spirits Ingredient = Ingredient{"Spirits", Base}

	// Top Shelf
	Belladonna       Ingredient = Ingredient{"Belladonna", TopShelf}
	Chamomile        Ingredient = Ingredient{"Chamomile", TopShelf}
	Comfrey          Ingredient = Ingredient{"Comfrey", TopShelf}
	Dandelion        Ingredient = Ingredient{"Dandelion", TopShelf}
	ElderberryLeaves Ingredient = Ingredient{"Elderberry Leaves", TopShelf}
	Eyebright        Ingredient = Ingredient{"Eyebright", TopShelf}
	Feverfew         Ingredient = Ingredient{"Feverfew", TopShelf}
	Henbane          Ingredient = Ingredient{"Henbane", TopShelf}
	HerbParis        Ingredient = Ingredient{"Herb Paris", TopShelf}
	Marigold         Ingredient = Ingredient{"Marigold", TopShelf}
	Mint             Ingredient = Ingredient{"Mint", TopShelf}
	Nettle           Ingredient = Ingredient{"Nettle", TopShelf}
	Poppy            Ingredient = Ingredient{"Poppy", TopShelf}
	Sage             Ingredient = Ingredient{"Sage", TopShelf}
	StJohnsWort      Ingredient = Ingredient{"St. John's Wort", TopShelf}
	Thistle          Ingredient = Ingredient{"Thistle", TopShelf}
	Valerian         Ingredient = Ingredient{"Valerian", TopShelf}
	Wormwood         Ingredient = Ingredient{"Wormwood", TopShelf}

	// Bottom Shelf
	AmanitaMuscaria Ingredient = Ingredient{"Amanita Muscaria", BottomShelf}
	BoarsTusk       Ingredient = Ingredient{"Boar's Tusk", BottomShelf}
	Cobweb          Ingredient = Ingredient{"Cobweb", BottomShelf}
	Charcoal        Ingredient = Ingredient{"Charcoal", BottomShelf}
	Ginger          Ingredient = Ingredient{"Ginger", BottomShelf}
	LeachedCoal     Ingredient = Ingredient{"Leached Coal", BottomShelf}
	Saltpetre       Ingredient = Ingredient{"Saltpetre", BottomShelf}
	Sulphur         Ingredient = Ingredient{"Sulphur", BottomShelf}
)

func IngredientFromString(s string) (Ingredient, error) {
	s = utils.Strip(s)

	switch s {
	case "Water":
		return Water, nil
	case "Wine":
		return Wine, nil
	case "Oil":
		return Oil, nil
	case "Spirits":
		return Spirits, nil
	case "Belladonna":
		return Belladonna, nil
	case "Chamomile":
		return Chamomile, nil
	case "Comfrey":
		return Comfrey, nil
	case "Dandelion":
		return Dandelion, nil
	case "ElderberryLeaves":
		return ElderberryLeaves, nil
	case "Eyebright":
		return Eyebright, nil
	case "Feverfew":
		return Feverfew, nil
	case "Henbane":
		return Henbane, nil
	case "HerbParis":
		return HerbParis, nil
	case "Marigold":
		return Marigold, nil
	case "Mint":
		return Mint, nil
	case "Nettle":
		return Nettle, nil
	case "Poppy":
		return Poppy, nil
	case "Sage":
		return Sage, nil
	case "StJohnsWort":
		return StJohnsWort, nil
	case "Thistle":
		return Thistle, nil
	case "Valerian":
		return Valerian, nil
	case "Wormwood":
		return Wormwood, nil
	case "AmanitaMuscaria":
		return AmanitaMuscaria, nil
	case "BoarsTusk":
		return BoarsTusk, nil
	case "Cobweb":
		return Cobweb, nil
	case "Charcoal":
		return Charcoal, nil
	case "Ginger":
		return Ginger, nil
	case "LeachedCoal":
		return LeachedCoal, nil
	case "Saltpetre":
		return Saltpetre, nil
	case "Sulphur":
		return Sulphur, nil
	default:
		return Water, fmt.Errorf("Invalid Ingredient: %s", s)
	}
}

func (a *Ingredient) UnmarshalYAML(unmarshal func(any) error) error {
	var s string
	err := unmarshal(&s)
	if err != nil {
		return err
	}

	b, err := IngredientFromString(s)

	*a = b

	return nil
}

func (i Ingredient) Name() string {
	return i.string
}

func (i Ingredient) IsBase() bool {
	return i.IngredientType == Base
}

func (i Ingredient) BottomShelf() bool {
	return i.IngredientType == BottomShelf
}
