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

package home

import (
	"context"
	"net/http"

	"dev.tandem.ws/tandem/camper/pkg/auth"
	"dev.tandem.ws/tandem/camper/pkg/carousel"
	"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) {
		switch r.Method {
		case http.MethodGet:
			home := newHomePage()
			home.MustRender(w, r, user, company, conn)
		default:
			httplib.MethodNotAllowed(w, r, http.MethodGet)
		}
	})
}

type homePage struct {
	*template.PublicPage
	Cover         []*carousel.Slide
	CampsiteTypes []*campsiteType
	Carousel      []*carousel.Slide
	Slogan        string
}

func newHomePage() *homePage {
	return &homePage{PublicPage: template.NewPublicPage()}
}

func (p *homePage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
	p.Setup(r, user, company, conn)
	p.CampsiteTypes = mustCollectCampsiteTypes(r.Context(), company, conn, user.Locale)
	p.Cover = carousel.MustCollectSlides(r.Context(), company, conn, user.Locale, coverName)
	p.Carousel = carousel.MustCollectSlides(r.Context(), company, conn, user.Locale, carouselName)
	var err error
	p.Slogan, err = conn.GetText(r.Context(), "select coalesce(i18n.slogan, home.slogan) from home left join camper.home_i18n as i18n on i18n.company_id = home.company_id and i18n.lang_tag = $1 where home.company_id = $2", user.Locale.Language, company.ID)
	if err != nil && !database.ErrorIsNotFound(err) {
		panic(err)
	}
	template.MustRenderPublic(w, r, user, company, "home.gohtml", p)
}

type campsiteType struct {
	Label string
	HRef  string
	Media string
}

func mustCollectCampsiteTypes(ctx context.Context, company *auth.Company, conn *database.Conn, loc *locale.Locale) []*campsiteType {
	rows, err := conn.Query(ctx, `
		select coalesce(i18n.name, campsite_type.name) as l10_name
		     , '/campsites/types/' || slug
		     , media.path
		from campsite_type
		    left join campsite_type_i18n as i18n on campsite_type.campsite_type_id = i18n.campsite_type_id and lang_tag = $1
		    join media using (media_id)
		where campsite_type.company_id = $2
		  and campsite_type.active
        order by position, l10_name
	`, loc.Language, company.ID)
	if err != nil {
		panic(err)
	}
	defer rows.Close()

	localePath := "/" + loc.Language.String()
	var items []*campsiteType
	for rows.Next() {
		item := &campsiteType{}
		err = rows.Scan(&item.Label, &item.HRef, &item.Media)
		if err != nil {
			panic(err)
		}
		item.HRef = localePath + item.HRef
		items = append(items, item)
	}
	if rows.Err() != nil {
		panic(rows.Err())
	}

	return items
}