package main

import (
	"database/sql"
	"fmt"
	"log"

	"github.com/go-sql-driver/mysql"
	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/static"
)

type Video struct {
	Id  int64
	Url string
}

type Subtitle struct {
	Id       int64
	Timecode int64
	Subtitle string
	Video    int64
}

type Response struct {
	Video    string
	Timecode []int64
}

var db *sql.DB

func formatResponse(c fiber.Ctx) error {
	regex := c.Query("query")

	var ret []Response
	subtitles := getSubtitles(regex)

	var lastVideoId int64 = -1
	var currVideoId int64 = -1

	var listTimecode []int64 = nil

	for _, element := range subtitles {
		currVideoId = element.Video

		//fmt.Println("curr %d et last %d", currVideoId, lastVideoId)
		if currVideoId != lastVideoId {
			if lastVideoId != -1 {
				//fmt.Println("inside")
				tmpVideo := getVideo(lastVideoId)
				ret = append(ret, Response{tmpVideo.Url, listTimecode})
			}

			listTimecode = nil
			lastVideoId = currVideoId
		}

		listTimecode = append(listTimecode, element.Timecode)
		//fmt.Println(listTimecode)
	}

	tmpVideo := getVideo(lastVideoId)
	ret = append(ret, Response{tmpVideo.Url, listTimecode})

	//fmt.Println("================")
	//fmt.Println(ret)

	return c.JSON(ret)
}

func getVideo(id int64) Video {
	var ret Video
	row := db.QueryRow("SELECT * FROM video WHERE id = ?", id)

	//defer row.Close()

	if err := row.Scan(&ret.Id, &ret.Url); err != nil {
		fmt.Println(err)
		return ret
	}

	return ret
}

func getSubtitles(regex string) []Subtitle {
	//fmt.Println(regex)
	var ret []Subtitle
	//rows, err := db.Query("SELECT id, timecode, video, MATCH (subtitle) AGAINST (?)   FROM subtitle GROUP BY video, timecode, subtitle, id", regex)
	rows, err := db.Query("SELECT * FROM subtitle WHERE MATCH (subtitle) AGAINST (?) GROUP BY video, id ORDER BY video, timecode", regex)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	//fmt.Println(rows)

	defer rows.Close()

	for rows.Next() {
		var subtitle Subtitle
		if err := rows.Scan(&subtitle.Id, &subtitle.Timecode, &subtitle.Subtitle, &subtitle.Video); err != nil {
			//if err := rows.Scan(&subtitle.Id, &subtitle.Timecode, &subtitle.Subtitle, &subtitle.Video); err != nil {
			fmt.Println(err)
			return nil
		}

		ret = append(ret, subtitle)
		//fmt.Println(ret)
	}

	if err := rows.Err(); err != nil {
		fmt.Println(err)
	}

	return ret
}

func main() {
	cfg := mysql.Config{
		//User:   os.Getenv("DBUSER"),
		//Passwd: os.Getenv("DBPASS"),
		User:   "test",
		Passwd: "test",
		Net:    "tcp",
		Addr:   "127.0.0.1:3306",
		DBName: "db",
	}
	// Get a database handle.
	var err error
	db, err = sql.Open("mysql", cfg.FormatDSN())
	if err != nil {
		log.Fatal(err)

	}

	pingErr := db.Ping()
	if pingErr != nil {
		log.Fatal(pingErr)

	}

	fmt.Println("Connected!")

	app := fiber.New()

	/*
		app.Get("/", func(c fiber.Ctx) error {
			return c.SendString("Hello, World")
		})
	*/

	//app.Static("/", "../frontend/.output/public")
	app.Get("/*", static.New("../front/.output/public"))

	app.Get("/search", formatResponse)

	app.Listen(":8080")
}