package main

import (
	"context"
	"fmt"
	"log"
	"net/http"

	"git.agecem.com/bottin/bottin/v10/pkg/bottin"
	"github.com/labstack/echo/v4"
)

// Handling
func UIIndex(ctx context.Context, bottinClient *bottin.APIClient, dbClient *DBClient) echo.HandlerFunc {
	return func(c echo.Context) error {
		type data struct {
			Error                string
			BottinHealthResponse bottin.ReadHealthResponse
			IsDBUp               bool
			Result               string
		}

		return c.Render(http.StatusOK, "app", func() (d data) {
			if err := func() error {
				select {
				case <-ctx.Done():
					return fmt.Errorf("Impossible de contacter le serveur: %s", ctx.Err())
				default:
					// Check client
					if bottinClient == nil {
						return fmt.Errorf("Impossible de contacter le serveur, le client API est nil")
					}

					// Check bottin health
					bottinHealthResponse, err := bottinClient.ReadHealth(ctx)
					if err != nil {
						return err
					}
					d.BottinHealthResponse = bottinHealthResponse

					// Check db health
					if dbClient == nil {
						return fmt.Errorf("Impossible de contacter la base de données, le client DB est nil")
					}

					if err := dbClient.Ping(ctx); err != nil {
						return err
					}
					d.IsDBUp = true

					// No errors
					return nil
				}
			}(); err != nil {
				// Send error to user
				d.Error = err.Error()

				// Log error
				log.Println("err:", d.Error)
			}
			return
		}())
	}
}

/*
UICreateTransaction gère la création des transactions

TODO:
  - Fully implement
  - Check context is not closed
*/
func UICreateTransaction(ctx context.Context, cfg Config, bottinClient *bottin.APIClient, dbClient *DBClient) echo.HandlerFunc {
	return func(c echo.Context) error {
		type data struct {
			Error  string
			Result string
			//BottinHealth bottin.ReadHealthResponse
		}

		return c.Render(http.StatusOK, "app", func() (d data) {
			if err := func() error {
				if bottinClient == nil {
					return fmt.Errorf("Cannot operate on nil *bottin.APIClient")
				}

				/*
					bottinReadHealthResponse, err := bottinClient.ReadHealth(ctx)
					if err != nil {
						return err
					}

					d.BottinHealth = bottinReadHealthResponse
				*/

				isPerpetual := c.FormValue("is_perpetual") == "on"
				membreID := c.FormValue("membre_id")

				if membreID == "" {
					return fmt.Errorf("Aucun numéro étudiant sélectionné. Assurez-vous de cliquer sur la case 'Numéro étudiant:' avant de scanner.")
				}

				//TODO check if membre already received before checking bottin

				// check if membre exists in bottin
				membreResponse, err := bottinClient.ReadMembre(ctx, membreID)
				if err != nil {
					if err.Error() == "400 no rows in result set" {
						return fmt.Errorf("Numéro étudiant introuvable %s", membreID)
					}
					return err
				}

				if membreResponse.Data.Membre.ID != membreID {
					return fmt.Errorf("Bottin a retourné '%s' en demandant '%s'", membreID, membreResponse.Data.Membre.ID)
				}

				// dbclient.CreateTransaction
				if err := dbClient.CreateTransaction(ctx, Transaction{
					MembreID:    membreID,
					IsPerpetual: isPerpetual,
				}); err != nil {
					return err
				}

				// Prepare result message
				d.Result = fmt.Sprintf("Membre %s peut recevoir son agenda %s",
					membreID,
					func() string {
						if isPerpetual {
							return "perpétuel"
						} else {
							return "non-perpétuel"
						}
					}(),
				)

				return nil
			}(); err != nil {
				d.Error = err.Error()
				log.Println("err:", d.Error)
			}
			return
		}())
	}
}