/*
 * SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package surroundings

import (
	"context"
	gotemplate "html/template"
	"net/http"

	"dev.tandem.ws/tandem/camper/pkg/auth"
	"dev.tandem.ws/tandem/camper/pkg/database"
	httplib "dev.tandem.ws/tandem/camper/pkg/http"
	"dev.tandem.ws/tandem/camper/pkg/locale"
	"dev.tandem.ws/tandem/camper/pkg/template"
)

type PublicHandler struct {
}

func NewPublicHandler() *PublicHandler {
	return &PublicHandler{}
}

func (h *PublicHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var head string
		head, r.URL.Path = httplib.ShiftPath(r.URL.Path)
		switch head {
		case "":
			switch r.Method {
			case http.MethodGet:
				page := newSurroundingsPage()
				page.MustRender(w, r, user, company, conn)
			default:
				httplib.MethodNotAllowed(w, r, http.MethodGet)
			}
		default:
			http.NotFound(w, r)
		}
	})
}

type surroundingsPage struct {
	*template.PublicPage
	Ad         *surroundingsAd
	Highlights []*highlight
}

func newSurroundingsPage() *surroundingsPage {
	return &surroundingsPage{PublicPage: template.NewPublicPage()}
}

func (p *surroundingsPage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
	p.Setup(r, user, company, conn)
	p.Highlights = mustCollectSurroundings(r.Context(), company, conn, user.Locale)
	p.Ad = mustCollectAd(r.Context(), company, conn, user.Locale)
	template.MustRenderPublic(w, r, user, company, "surroundings.gohtml", p)
}

type highlight struct {
	Media       string
	Name        string
	Description gotemplate.HTML
}

func mustCollectSurroundings(ctx context.Context, company *auth.Company, conn *database.Conn, loc *locale.Locale) []*highlight {
	rows, err := conn.Query(ctx, `
		select media.path
		     , coalesce(i18n.name, highlight.name) as l10_name
		     , coalesce(i18n.description, highlight.description)::text as l10_description
		from surroundings_highlight as highlight
		    join media using (media_id)
		    left join surroundings_highlight_i18n as i18n on highlight.surroundings_highlight_id = i18n.surroundings_highlight_id and lang_tag = $1
		where highlight.company_id = $2
		order by position
		       , l10_name
	`, loc.Language, company.ID)
	if err != nil {
		panic(err)
	}
	defer rows.Close()

	var items []*highlight
	for rows.Next() {
		item := &highlight{}
		err = rows.Scan(&item.Media, &item.Name, &item.Description)
		if err != nil {
			panic(err)
		}
		items = append(items, item)
	}
	if rows.Err() != nil {
		panic(rows.Err())
	}

	return items
}

type surroundingsAd struct {
	MediaURL string
	Title    string
	Anchor   string
	HRef     string
}

func mustCollectAd(ctx context.Context, company *auth.Company, conn *database.Conn, loc *locale.Locale) *surroundingsAd {
	ad := &surroundingsAd{}
	err := conn.QueryRow(ctx, `
		select media.path
		     , coalesce(i18n.title, ad.title) as l10_title
		     , coalesce(i18n.anchor, ad.anchor) as l10_anchor
		     , href::text
		from surroundings_ad as ad
		    join media using (media_id)
		    left join surroundings_ad_i18n as i18n on ad.company_id = i18n.company_id and lang_tag = $1
		where ad.company_id = $2
	`, loc.Language, company.ID).Scan(&ad.MediaURL, &ad.Title, &ad.Anchor, &ad.HRef)
	if err != nil {
		if database.ErrorIsNotFound(err) {
			return nil
		}
		panic(err)
	}
	return ad
}
