package page

import (
	"context"
	"io"
	"log/slog"
	"net/url"
	"strings"

	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
	"github.com/gomarkdown/markdown"
	"github.com/gomarkdown/markdown/ast"
	"github.com/gomarkdown/markdown/html"
	"github.com/gomarkdown/markdown/parser"
)

// image can be used to preload
type Image struct {
	SrcSet string
	Src    string
}

func (s *Service) getHTML(ctx context.Context, page PageHeader) (out []byte, imgs []Image, err error) {
	extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
	p := parser.NewWithExtensions(extensions)

	doc := p.Parse(page.md)

	// create HTML renderer with extensions
	htmlFlags := html.CommonFlags | html.HrefTargetBlank
	opts := html.RendererOptions{
		Flags:          htmlFlags,
		RenderNodeHook: imageMiddleware(page, &imgs),
	}
	renderer := html.NewRenderer(opts)

	out = markdown.Render(doc, renderer)
	return
}

func imageMiddleware(page PageHeader, imgs *[]Image) func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
	return func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
		if !entering {
			return ast.GoToNext, false
		}
		img, ok := node.(*ast.Image)
		if !ok {
			return ast.GoToNext, false
		}
		src := string(img.Destination)
		if strings.HasPrefix(src, ".attachments") {
			imgPath, err := url.PathUnescape(src)
			if err != nil {
				slog.Error("could not unescape path", "err", err)
				return ast.GoToNext, false
			}
			src, err = images.URLFromPath(page.UID + "/" + imgPath)
			if err != nil {
				slog.Error("could not get image url", "err", err)
				return ast.GoToNext, false
			}
			image := Image{
				SrcSet: images.SourceSet(src),
				Src:    src + "?w=1024",
			}

			img.Attribute = &ast.Attribute{Attrs: map[string][]byte{
				// "srcset":        []byte(image.SrcSet),
				"fetchpriority": []byte("low"),
				"loading":       []byte("lazy"),
				"class":         []byte("min-h-48"),
				"src":           []byte(image.Src),
			}}

			*imgs = append(*imgs, image)
			// // img.Attrs["srcset"] =

		}

		img.Destination = []byte(src)

		return ast.GoToNext, false
	}
}
