package controllers

import (
	m "skripsi/skripsiBackend/models"

	"database/sql"

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

	"github.com/revel/revel"
)

type Mahasiswa struct {
	*revel.Controller
}

func (c Mahasiswa) Show() 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()

	rows, err := db.Query("SELECT * FROM mahasiswa ORDER BY email")

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

	mahasiswas := []m.Mahasiswa{}
	for rows.Next() {
		mahasiswa := m.Mahasiswa{}
		if err := rows.Scan(&mahasiswa.ID, &mahasiswa.Nama, &mahasiswa.Email, &mahasiswa.Coin, &mahasiswa.Powerups, &mahasiswa.IsAdmin); err != nil {
			// revel.ERROR.Println("Baca data gagal:", err)
			return c.RenderText("Baca data gagal")
		}
		mahasiswas = append(mahasiswas, mahasiswa)
	}

	c.ViewArgs["Mahasiswa"] = mahasiswas

	// return c.RenderJSON(materis)
	return c.Render()

}

func (c Mahasiswa) Index(email string) 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 email == "" {
		rows, err = db.Query("SELECT * FROM mahasiswa ORDER BY id")
	} else {
		rows, err = db.Query("SELECT * FROM mahasiswa WHERE email=? ORDER BY id", email)
	}
	if err != nil {
		// revel.ERROR.Println("Query gagal:", err)
		return c.RenderText("Query gagal")
	}
	defer rows.Close()

	mahasiswas := []m.Mahasiswa{}
	for rows.Next() {
		mahasiswa := m.Mahasiswa{}
		if err := rows.Scan(&mahasiswa.ID, &mahasiswa.Email, &mahasiswa.Nama, &mahasiswa.Coin,&mahasiswa.Powerups, &mahasiswa.IsAdmin); err != nil {
			// revel.ERROR.Println("Baca data gagal:", err)
			return c.RenderText("Baca data gagal")
		}
		mahasiswas = append(mahasiswas, mahasiswa)
	}

	return c.RenderJSON(mahasiswas)
}

func (c Mahasiswa) GetAdmin(email string) 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 isAdmin bool
    err = db.QueryRow("SELECT IsAdmin FROM mahasiswa WHERE email=? LIMIT 1", email).Scan(&isAdmin)
    if err != nil {
        if err == sql.ErrNoRows {
            isAdmin = false 
        } else {
            return c.RenderText("Query gagal")
        }
    }

    return c.RenderJSON(isAdmin)
}

func (c Mahasiswa) GetID(email string) 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 ID int
    err = db.QueryRow("SELECT ID FROM mahasiswa WHERE email=? LIMIT 1", email).Scan(&ID)
    if err != nil {
        if err == sql.ErrNoRows {
            ID = -1
        } else {
            return c.RenderText("Query gagal")
        }
    }

    return c.RenderJSON(ID)
}

func (c Mahasiswa) GetPowerups(email string) 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 powerups int
    err = db.QueryRow("SELECT Powerups FROM mahasiswa WHERE email=? LIMIT 1", email).Scan(&powerups)
    if err != nil {
        if err == sql.ErrNoRows {
            powerups = -1
        } else {
            return c.RenderText("Query gagal")
        }
    }

    return c.RenderJSON(powerups)
}

func (c Mahasiswa) GetCoin(email string) 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 coin int
    err = db.QueryRow("SELECT Coin FROM mahasiswa WHERE email=? LIMIT 1", email).Scan(&coin)
    if err != nil {
        if err == sql.ErrNoRows {
            coin = -1
        } else {
            return c.RenderText("Query gagal")
        }
    }

    return c.RenderJSON(coin)
}

func (c Mahasiswa) Create(mahasiswa m.Mahasiswa) revel.Result {
	v := c.Validation
	mahasiswa.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 mahasiswa (nama, email, coin, powerups, isAdmin) VALUES (?, ?, ?, ?, ?)", mahasiswa.Nama, mahasiswa.Email, mahasiswa.Coin, mahasiswa.Powerups, mahasiswa.IsAdmin)
	if err != nil {
		if mysqlError, ok := err.(*mysql.MySQLError); ok {
			if mysqlError.Number == 1062 {
				return c.RenderText("ID sudah ada")
			}
		}
		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Insert data gagal")
	}

	
	return c.RenderText("Data mahasiswa berhasil ditambahkan")

}

func (c Mahasiswa) ChangePowerups(email string, mahasiswa m.Mahasiswa) 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()

	_, err = db.Exec("UPDATE mahasiswa SET powerups=? WHERE email=?", mahasiswa.Powerups, email)
	if err != nil {

		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Update data gagal")
	}

	return c.RenderText("Powerups berhasil diganti")
}

func (c Mahasiswa) ChangeCoin(email string, mahasiswa m.Mahasiswa) 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()

	_, err = db.Exec("UPDATE mahasiswa SET coin=? WHERE email=?", mahasiswa.Coin, email)
	if err != nil {

		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Update data gagal")
	}

	return c.RenderText("Coin berhasil diganti")
}

func (c Mahasiswa) SetAsAdmin(id int, mahasiswa m.Mahasiswa) 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()

	_, err = db.Exec("UPDATE mahasiswa SET isAdmin=? WHERE id=?", mahasiswa.IsAdmin, id)
	if err != nil {

		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Update data gagal")
	}

	return c.RenderText("Akses admin baru berhasil diberikan")
}

func (c Mahasiswa) Delete(id 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()

	_, err = db.Exec("DELETE FROM mahasiswa WHERE ID=?", id)
	if err != nil {
		// Handle error here
		return c.RenderText("Delete data gagal")
	}

	return c.RenderText("Data mahasiswa berhasil dihapus")
}
