package yimg

import (
	"errors"
	"strings"

	"gopkg.in/yaml.v2"
)

// Images is a mapping of size to Image
// Size is represented by widthxheight or just height, for example 1920x1080 or 480
type Images map[string]Image

var (
	ErrYamlMissingField = errors.New("image metadata is missing necessary field")
)

func (images Images) Size(size string) *string {
	if i, ok := images[size]; ok {
		return &i.URL
	}
	return nil
}

func (images *Images) Marshal(ratio *float64) (*string, error) {
	if images == nil {
		return nil, nil
	}
	keys := []string{}
	for key := range *images {
		keys = append(keys, key)
	}

	if len(*images) == 0 || len(keys) == 0 {
		return nil, nil
	}

	var format string
	var uid string
	var newFormat bool
	format = (*images)[keys[0]].Format
	uid = (*images)[keys[0]].Uid
	newFormat = (*images)[keys[0]].NewFormat

	sizes := []string{}
	heights := []string{}
	for i := range keys {
		if !strings.Contains(keys[i], "x") {
			size := (*images)[keys[i]].Size
			if strings.Contains(size, "x") {
				sizes = append(sizes, size)
			} else {
				heights = append(heights, keys[i])
			}
		} else {
			sizes = append(sizes, keys[i])
		}
	}

	metaData := yamlData{
		Sizes:     sizes,
		Heights:   heights,
		Format:    format,
		Uid:       uid,
		NewFormat: newFormat,
	}

	if ratio != nil {
		metaData.Ratio = *ratio
	}

	b, err := yaml.Marshal(metaData)
	if err != nil {
		return nil, err
	}

	marshalled := string(b)
	return &marshalled, err
}

// Image contains the fully qualified URL of an image and any known metadata
type Image struct {
	Width     int    `json:"width,omitempty"`
	Height    int    `json:"height"`
	URL       string `json:"url"`
	Uid       string `json:"uid"`
	Size      string `json:"size"`
	Format    string `json:"format"`
	NewFormat bool   `json:"new_format"`
}

func (i Image) validate() error {
	if i.Format == "" || i.Uid == "" {
		return ErrYamlMissingField
	}
	return nil
}
