package wikipress

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"time"

	"github.com/yuin/goldmark"
	"github.com/yuin/goldmark/extension"
	"github.com/yuin/goldmark/renderer/html"
)

type Version struct {
	Author struct {
		Name string
	}
	Message       string
	Date          time.Time
	content       string
	contentbinary []byte
	Hash          string
}

func (v Version) GetBody() string {
	details := strings.SplitN(v.content, "---", 2)
	if len(details) == 2 {
		return details[1]
	}

	return ""
}

func (v Version) GetHeaders() map[string]string {
	details := strings.SplitN(v.content, "---", 2)
	if len(details) < 2 {
		return make(map[string]string)
	}

	lines := strings.Split(details[0], "\n")
	headers := make(map[string]string)
	for _, line := range lines {
		lineContent := strings.SplitN(line, ":", 2)
		if len(lineContent) != 2 {
			continue
		}
		headers[lineContent[0]] = strings.TrimSpace(lineContent[1])
	}

	return headers
}

func (v Version) GetHeader(name, defaultValue string) string {
	headers := v.GetHeaders()
	val, ok := headers[name]
	if ok {
		return val
	}
	return defaultValue
}

func (v Version) GetHeaderInt(name string, defaultValue int) int {
	headers := v.GetHeaders()
	val, ok := headers[name]
	if ok {
		vali, err := strconv.Atoi(val)
		if err != nil {
			return defaultValue
		}
		return vali
	}
	return defaultValue
}

func (v Version) GetHTMLContent() (string, error) {
	mdParser := goldmark.New(
		goldmark.WithExtensions(
			extension.GFM,           // GitHub-Flavored Markdown (inkl. Tabellen, Tasklists)
			extension.Footnote,      // Fußnoten
			extension.Table,         // Tabellen (redundant, aber explizit)
			extension.Strikethrough, // Durchgestrichener Text
			extension.DefinitionList,
			extension.TaskList,
		),
		goldmark.WithRendererOptions(
			html.WithHardWraps(),
			html.WithUnsafe(), // erlaubt raw HTML (vorsichtig!)
		),
	)

	var buf bytes.Buffer
	err := mdParser.Convert([]byte(v.GetBody()), &buf)
	if err != nil {
		return "", fmt.Errorf("%w: %s", ErrCantParseMarkdownToHTML, err)
	}

	return buf.String(), nil
}
