package api

import (
	"encoding/csv"
	"fmt"
	"net/http"
	"sort"
	"strconv"

	"github.com/gorilla/mux"
)

type FlatMaps []map[string]any

func (maps FlatMaps) GetHeaders() (res []string) {
	keys := map[string]bool{}
	for _, m := range maps {
		for k, _ := range m {
			if _, ok := keys[k]; !ok {
				keys[k] = true
				res = append(res, k)
			}
		}
	}
	sort.Strings(res)
	return
}

func (maps FlatMaps) GetValues() (res [][]string) {
	headers := maps.GetHeaders()
	for _, m := range maps {
		line := []string{}
		for _, k := range headers {
			if v, ok := m[k]; ok && v != nil {
				line = append(line, fmt.Sprint(v))
			} else {
				line = append(line, "")
			}
		}
		res = append(res, line)
	}
	return
}

func (h APIHandler) CacheExport(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	cacheid := vars["cacheid"]

	d, err := h.cache.Get(cacheid)
	if err != nil {
		fmt.Println(err)
		w.WriteHeader(http.StatusNotFound)
		return
	}

	if data, ok := d.([]any); ok {

		flatmaps := FlatMaps{}
		//fmt.Println(data)

		for _, v := range data {
			fm := map[string]any{}
			flatten("", v.(map[string]any), fm)
			flatmaps = append(flatmaps, fm)
		}

		w.Header().Set("Content-Type", "text/csv")
		w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=export-%s.csv", cacheid))
		c := csv.NewWriter(w)
		c.Write(flatmaps.GetHeaders())
		c.WriteAll(flatmaps.GetValues())
		return

	}

	w.WriteHeader(http.StatusNotFound)

}

func flatten(prefix string, src map[string]any, dest map[string]any) {
	if len(prefix) > 0 {
		prefix += "."
	}
	for k, v := range src {
		switch child := v.(type) {
		case map[string]any:
			flatten(prefix+k, child, dest)
		case []any:
			for i := 0; i < len(child); i++ {
				dest[prefix+k+"."+strconv.Itoa(i)] = child[i]
			}
		default:
			fmt.Println(prefix+k, " : ", v)
			dest[prefix+k] = v
		}
	}
}
