package tiles

import (
	"fmt"
	"strings"
	"time"

	"git.coopgo.io/coopgo-platform/carpool-service/internal"
	"github.com/google/uuid"
	"github.com/paulmach/orb/geojson"
	"github.com/rs/zerolog/log"
)

// Tiles are defined as :
// - "driver" or "passenger" string depending on the status of the journeys included in the tiles
// - a date formatted as "2006-01-02"
// - Bounds of the tile
type Tile struct {
	DriverOrPassenger string
	Date              string // Date formatted as "2006-01-02"
	GridId            GridId

	TiledRoutes []TiledRoute
}

func (tile *Tile) ID() string {
	return fmt.Sprintf("%s/%s/%d", tile.DriverOrPassenger, tile.Date, tile.GridId)
}

// GetTile retrieves a tile from persistant storage or cache
func (h *TilesHandler) GetTile(driverOrPassenger string, date time.Time, gridid GridId) (*Tile, error) {
	log.Debug().
		Str("driver_or_passenger", driverOrPassenger).
		Str("date", date.Format("2006-01-02")).
		Any("grid_id", gridid).
		Msg("GetTile")

	routes := []*geojson.FeatureCollection{}
	day := strings.ToUpper(date.Format("Mon"))
	dateString := date.Format("2006-01-02")

	if driverOrPassenger == "driver" {
		regroutes, err := h.PersistentStorage.GetDriverRegularRoutesForTile(day, int64(gridid))
		if err != nil {
			return nil, err
		}

		routes = regroutes
	} else if driverOrPassenger == "passenger" {
		regroutes, err := h.PersistentStorage.GetPassengerRegularRoutesForTile(day, int64(gridid))
		if err != nil {
			return nil, err
		}

		routes = regroutes
	}

	date0h, _ := time.Parse("2006-01-02", dateString)
	date24h := date0h.Add(24 * time.Hour)

	result := []TiledRoute{}

	for _, r := range routes {

		rr := internal.RegularRoute(*r)
		schedules, err := rr.PlannedRouteSchedules(date0h, date24h)
		if err != nil {
			log.Error().Err(err)
			return nil, err
		}

		if len(schedules) > 0 {
			tiledRoute := TiledRoute{
				ID:            uuid.NewString(),
				Route:         r,
				Type:          TiledRouteRegular,
				DepartureDate: schedules[0].DepartureDate,
			}

			result = append(result, tiledRoute)
		}
	}

	return &Tile{
		DriverOrPassenger: driverOrPassenger,
		Date:              dateString,
		GridId:            gridid,
		TiledRoutes:       result,
	}, nil
}