package server

import (
	"fmt"
	"net/http"
	"path"
	"time"

	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/gallery"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/page"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/translate"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/rest"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/restgallery"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/resthome"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/restimage"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/filesystem"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/middleware"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/pkg/templer"
	"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/web/layouts"
	"github.com/studio-b12/gowebdav"
	"github.com/valkey-io/valkey-go"
)

func (s *Server) allRoutes() (h http.Handler, err error) {
	mux := http.NewServeMux()

	registerStatic(mux)

	other, err := s.dynamicRoutes()
	if err != nil {
		return
	}

	mux.Handle("/", other)

	h = mux
	h = templer.Middleware(h)
	h = middleware.Logging(h)
	return h, nil
}

func (s *Server) dynamicRoutes() (h http.Handler, err error) {
	mux := http.NewServeMux()

	webdavClient := gowebdav.NewClient(s.cfg.FileSystem.URL, s.cfg.FileSystem.User, s.cfg.FileSystem.Password)
	err = webdavClient.Connect()
	if err != nil {
		err = fmt.Errorf("could not connect webdavClient: %w", err)
		return
	}

	var fs filesystem.FS = webdavClient

	valkeyClient, err := valkey.NewClient(valkey.ClientOption{
		InitAddress: s.cfg.Cache.InitAddress,
		Password:    s.cfg.Cache.Password,
	})
	if err != nil {
		err = fmt.Errorf("failed to create valkey client: %w", err)
		return
	}
	if err != nil {
	} else {
		fs = filesystem.NewCachedClient(webdavClient, valkeyClient, s.cfg.Cache.RefreshTime, s.cfg.Cache.LifeTime)
	}
	imageSrv := images.New(fs, s.cfg.Image, valkeyClient)

	mux.Handle("/images/", rest.Use(
		restimage.New(imageSrv),
		middleware.Cache(time.Hour*24*5),
	))

	translator := translate.New()
	renderer := layouts.New(s.cfg)

	mux.Handle("/", rest.Use(
		func() http.Handler {
			mux := http.NewServeMux()

			mux.Handle(path.Join("/"+s.cfg.Gallery.Path), restgallery.New(renderer, gallery.New(fs, s.cfg.Gallery, imageSrv, valkeyClient), s.cfg.Gallery))
			mux.Handle("/", resthome.New(renderer, page.New(fs)))

			return mux
		}(),
		translator.Middleware,
		middleware.Cache(time.Minute),
	))

	return mux, nil
}
