package controllers

import (
	m "skripsi/skripsiBackend/models"

	"database/sql"

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

	"github.com/revel/revel"
)

type Materi struct {
	*revel.Controller
}

func (c Materi) Index(kodeMK 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 kodeMK != "" {
		rows, err = db.Query("SELECT materi.*, mata_kuliah.Nama FROM materi JOIN mata_kuliah ON materi.Kode_MK = mata_kuliah.Kode_MK WHERE mata_kuliah.Kode_MK=?", kodeMK)

	} else {
		rows, err = db.Query("SELECT materi.*, mata_kuliah.Nama FROM materi JOIN mata_kuliah ON materi.Kode_MK = mata_kuliah.Kode_MK")

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

	materis := []m.Materi{}
	for rows.Next() {
		materi := m.Materi{}
		if err := rows.Scan(&materi.ID, &materi.Nama, &materi.Deskripsi, &materi.Kode_MK, &materi.MataKuliah.Nama); err != nil {
			// revel.ERROR.Println("Baca data gagal:", err)
			return c.RenderText("Baca data gagal")
		}
		materis = append(materis, materi)
	}

	return c.RenderJSON(materis)
}

func (c Materi) IndexById(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()

	rows, err := db.Query("SELECT materi.*, mata_kuliah.Nama FROM materi LEFT JOIN mata_kuliah ON materi.Kode_MK = mata_kuliah.Kode_MK WHERE materi.ID=?", id_materi)

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

	materis := []m.Materi{}
	for rows.Next() {
		materi := m.Materi{}
		if err := rows.Scan(&materi.ID, &materi.Nama, &materi.Deskripsi, &materi.Kode_MK, &materi.MataKuliah.Nama); err != nil {
			// revel.ERROR.Println("Baca data gagal:", err)
			return c.RenderText("Baca data gagal")
		}
		materis = append(materis, materi)
	}

	return c.RenderJSON(materis)
}

func (c Materi) Create(materi m.Materi) revel.Result {
	v := c.Validation
	materi.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 materi (nama, deskripsi, kode_MK) VALUES (?, ?, ?)", materi.Nama, materi.Deskripsi, materi.Kode_MK)
	if err != nil {
		if mysqlError, ok := err.(*mysql.MySQLError); ok {
			if mysqlError.Number == 1062 {
				return c.RenderText("ID materi sudah ada")
			}
		}
		//  revel.ERROR.Println("Insert data gagal:", err)
		return c.RenderText("Insert data gagal")
	}

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

func (c Materi) Update(id int, materi m.Materi) revel.Result {
	v := c.Validation
	materi.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 materi SET nama=?, deskripsi=?, kode_MK=? WHERE ID=?", materi.Nama, materi.Deskripsi, materi.Kode_MK, id)
	if err != nil {
		// Handle error here
		return c.RenderText("Update data gagal")
	}

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

func (c Materi) 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 materi WHERE ID=?", id)
	if err != nil {
		// Handle error here
		return c.RenderText("Delete data gagal")
	}

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