package controllers

import (
	m "skripsi/skripsiBackend/models"

	"database/sql"

	"github.com/go-sql-driver/mysql"

	"github.com/revel/revel"
)

type Leaderboard struct {
	*revel.Controller
}

func (c Leaderboard) Index(ID_materi int) revel.Result {
	db, err := sql.Open("mysql", revel.Config.StringDefault("db.spec", ""))
	if err != nil {
		// revel.ERROR.Println("Koneksi database gagal:", err)
		return c.RenderText("Koneksi database gagal")
	}

	defer db.Close()
	var rows *sql.Rows
	if ID_materi > 0 {
		rows, err = db.Query("SELECT leaderboard.*, mahasiswa.* FROM `leaderboard` LEFT JOIN mahasiswa on mahasiswa.ID=leaderboard.ID_player WHERE ID_materi=? ORDER BY skor DESC LIMIT 10", ID_materi)

	} else {
		rows, err = db.Query("SELECT leaderboard.*, mahasiswa.* FROM `leaderboard` LEFT JOIN mahasiswa on mahasiswa.ID=leaderboard.ID_player ORDER BY skor DESC LIMIT 10")

	}

	if err != nil {
		// revel.ERROR.Println("Query gagal:", err)
		return c.RenderText("Query gagal")
	}
	defer rows.Close()

	leaderboards := []m.Leaderboard{}
	for rows.Next() {
		leaderboard := m.Leaderboard{}

		if err := rows.Scan(&leaderboard.ID, &leaderboard.Skor, &leaderboard.ID_materi, &leaderboard.ID_player, &leaderboard.Mahasiswa.ID, &leaderboard.Mahasiswa.Email, &leaderboard.Mahasiswa.Nama, &leaderboard.Mahasiswa.Coin, &leaderboard.Mahasiswa.Powerups, &leaderboard.Mahasiswa.IsAdmin); err != nil {
			// revel.ERROR.Println("Baca data gagal:", err)
			return c.RenderText("Baca data gagal")
		}
		leaderboards = append(leaderboards, leaderboard)
	}

	return c.RenderJSON(leaderboards)
}

func (c Leaderboard) GetHighScore(ID_player int, ID_materi int) revel.Result {
	db, err := sql.Open("mysql", revel.Config.StringDefault("db.spec", ""))
	if err != nil {
		return c.RenderText("Koneksi database gagal")
	}
	defer db.Close()

	var score int
	err = db.QueryRow("SELECT Skor FROM leaderboard WHERE ID_player=? AND ID_materi=? LIMIT 1", ID_player, ID_materi).Scan(&score)
	if err != nil {
		if err == sql.ErrNoRows {
			score = -1
		} else {
			return c.RenderText("Query gagal")
		}
	}

	return c.RenderJSON(score)
}

func (c Leaderboard) Create(leaderboard m.Leaderboard) revel.Result {
	v := c.Validation
	leaderboard.Validate(v)
	if v.HasErrors() {
		return c.RenderText("Validasi gagal")
	}

	db, err := sql.Open("mysql", revel.Config.StringDefault("db.spec", ""))
	if err != nil {
		// revel.ERROR.Println("Koneksi database gagal:", err)
		return c.RenderText("Koneksi database gagal")
	}
	defer db.Close()

	_, err = db.Exec("INSERT INTO leaderboard (skor, ID_materi, ID_player) VALUES (?, ?, ?)", leaderboard.Skor, leaderboard.ID_materi, leaderboard.ID_player)
	if err != nil {
		if mysqlError, ok := err.(*mysql.MySQLError); ok {
			if mysqlError.Number == 1062 {
				return c.RenderText("ID leaderboard sudah ada")
			}
		}
		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Insert data gagal")
	}

	return c.RenderText("Data leaderboard berhasil ditambahkan")
}

func (c Leaderboard) Update(leaderboard m.Leaderboard) revel.Result {
	v := c.Validation
	leaderboard.Validate(v)
	if v.HasErrors() {
		return c.RenderText("Validasi gagal")
	}

	db, err := sql.Open("mysql", revel.Config.StringDefault("db.spec", ""))
	if err != nil {
		return c.RenderText("Koneksi database gagal")
	}
	defer db.Close()

	_, err = db.Exec("UPDATE leaderboard SET skor=? WHERE ID_materi=? AND ID_player=?", leaderboard.Skor, leaderboard.ID_materi, leaderboard.ID_player)
	if err != nil {
		// Handle error here
		return c.RenderText("Update data gagal")
	}

	return c.RenderText("Data leaderboard berhasil diupdate")
}