package handlers

import (
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"git.soup.land/soup/lookbook/internal/components"
	"git.soup.land/soup/lookbook/internal/data/image"
	"git.soup.land/soup/lookbook/internal/data/item"
	"git.soup.land/soup/lookbook/internal/data/tag"
	"git.soup.land/soup/sxgo/ssr"
)

type galleryPageData struct {
	Items    []galleryItem
	Tags     []tag.Row
	HasAuth  bool
	TagNames []string
}

type galleryItem struct {
	Item        item.Row
	Thumb       *image.Ref
	TagNames    []string
	TagListText string
}

func (g galleryPageData) Render(sw *ssr.Writer) error {
	return sw.Tmpl(g, `
<section class="hero">
	<form method="POST" action="/items" data-auth-required {{if not .HasAuth}}hidden{{end}}>
		<input type="url" name="url" placeholder="Paste a link" required>
		<button type="submit">Add</button>
	</form>
	<div class="notice" data-auth-status>Read only</div>
</section>

<section class="filters">
	{{range .Tags}}
	<button type="button" class="filter-pill" data-tag-filter="{{.Name}}">{{.Name}}</button>
	{{end}}
	<div class="tag-suggestions" data-tag-suggestions data-tags='{{json .TagNames}}'></div>
</section>

<section class="gallery">
	{{range .Items}}
	<div class="card" data-item-tags="{{.TagListText}}">
		<a href="/items/{{.Item.ID}}">
			{{if .Thumb}}
			<img src="/images/{{.Thumb.ID}}" alt="{{.Item.Title}}">
			{{else}}
			<div class="placeholder">{{if .Item.Title}}{{.Item.Title}}{{else}}{{.Item.SourceURL}}{{end}}</div>
			{{end}}
			<div class="overlay">
				<div class="title">{{if .Item.Title}}{{.Item.Title}}{{else}}{{.Item.SourceURL}}{{end}}</div>
				<div class="tags">{{range $i, $tag := .TagNames}}{{if $i}} · {{end}}{{$tag}}{{end}}</div>
			</div>
		</a>
	</div>
	{{end}}
</section>
`)
}

func HandleGetGallery(rc *RequestContext, w http.ResponseWriter, r *http.Request) error {
	items, err := item.QList(r.Context(), rc.DB)
	if err != nil {
		return fmt.Errorf("list items: %w", err)
	}

	var itemIDs []int64
	for _, row := range items {
		itemIDs = append(itemIDs, row.ID)
	}

	thumbs, err := image.QListPrimaryRefsByItems(r.Context(), rc.DB, itemIDs)
	if err != nil {
		return fmt.Errorf("list thumbs: %w", err)
	}

	entries, err := tag.QListItemTags(r.Context(), rc.DB)
	if err != nil {
		return fmt.Errorf("list tags: %w", err)
	}

	itemTagNames := make(map[int64][]string)
	for _, entry := range entries {
		itemTagNames[entry.ItemID] = append(itemTagNames[entry.ItemID], entry.Name)
	}

	var cards []galleryItem
	for _, row := range items {
		tagNames := itemTagNames[row.ID]
		cards = append(cards, galleryItem{
			Item:        row,
			Thumb:       refOrNil(thumbs[row.ID]),
			TagNames:    tagNames,
			TagListText: strings.Join(tagNames, ","),
		})
	}

	tags, err := tag.QList(r.Context(), rc.DB)
	if err != nil {
		return fmt.Errorf("list tags: %w", err)
	}

	authed, err := isAuthenticated(r, rc)
	if err != nil {
		return fmt.Errorf("auth status: %w", err)
	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	sw := ssr.NewWriter(w, rc.TmplCache)

	var tagNames []string
	for _, row := range tags {
		tagNames = append(tagNames, row.Name)
	}

	data := galleryPageData{
		Items:    cards,
		Tags:     tags,
		HasAuth:  authed,
		TagNames: tagNames,
	}
	return components.Page{
		Title:   "Gallery",
		Content: data,
		ShowNav: true,
		HasAuth: authed,
	}.Render(sw)
}

func refOrNil(ref image.Ref) *image.Ref {
	if ref.ID == 0 {
		return nil
	}
	return &ref
}

func parseID(value string) (int64, error) {
	return strconv.ParseInt(value, 10, 64)
}
