const pool = require("../config/dbConnect");

class Kelompok {
  constructor(
    code,
    judul,
    nama,
    skema,
    dosen,
    ketua,
    anggota,
    accdospem,
    acckaprodi,
    lulus,
    laporanSatu,
    laporanDua,
    laporanTiga,
    komentarLaporanSatu,
    komentarLaporanDua,
    komentarLaporanTiga,
    revisiSatu,
    revisiDua,
    revisiTiga,
    finalProject
  ) {
    this._code = code;
    this._judul = judul;
    this._nama = nama;
    this._skema = skema;
    this._dosen = dosen;
    this._ketua = ketua;
    this._anggota = anggota;
    this._accdospem = accdospem;
    this._acckaprodi = acckaprodi;
    this._lulus = lulus;
    this._laporanSatu = laporanSatu;
    this._laporanDua = laporanDua;
    this._laporanTiga = laporanTiga;
    this._komentarLaporanSatu = komentarLaporanSatu;
    this._komentarLaporanDua = komentarLaporanDua;
    this._komentarLaporanTiga = komentarLaporanTiga;
    this._revisiSatu = revisiSatu;
    this._revisiDua = revisiDua;
    this._revisiTiga = revisiTiga;
    this._finalProject = finalProject;
  }

  get code() {
    return this._code;
  }

  set code(code) {
    if (!code) throw new Error("Invalid code value.");

    code = code.trim();
    if (code === "") throw new Error("Invalid code value.");

    this._code = code;
  }

  get judul() {
    return this._judul;
  }

  set judul(judul) {
    if (!judul) throw new Error("Invalid judul value.");

    judul = judul.trim();
    if (judul === "") throw new Error("Invalid judul value.");

    this._judul = judul;
  }

  get nama() {
    return this._nama;
  }

  set nama(nama) {
    if (!nama) throw new Error("Invalid nama value.");

    nama = nama.trim();
    if (nama === "") throw new Error("Invalid nama value.");

    this._nama = nama;
  }

  get skema() {
    return this._skema;
  }

  set skema(skema) {
    if (!skema) throw new Error("Invalid skema value.");

    skema = skema.trim();
    if (skema === "") throw new Error("Invalid skema value.");

    this._skema = skema;
  }

  get dosen() {
    return this._dosen;
  }

  set dosen(dosen) {
    if (!dosen) throw new Error("Invalid dosen value.");

    dosen = dosen.trim();
    if (dosen === "") throw new Error("Invalid dosen value.");

    this._dosen = dosen;
  }

  get ketua() {
    return this._ketua;
  }

  set ketua(ketua) {
    if (!ketua) throw new Error("Invalid ketua value.");

    ketua = ketua.trim();
    if (ketua === "") throw new Error("Invalid ketua value.");

    this._ketua = ketua;
  }

  get anggota() {
    return this._anggota;
  }

  set anggota(anggota) {
    if (!anggota) throw new Error("Invalid anggota value.");

    this._anggota = anggota;
  }

  get accdospem() {
    return this._accdospem;
  }

  set accdospem(accdospem) {
    if (typeof accdospem !== "boolean")
      throw new Error("Invalid accdospem value.");

    this._accdospem = accdospem;
  }

  get acckaprodi() {
    return this._acckaprodi;
  }

  set acckaprodi(acckaprodi) {
    if (typeof acckaprodi !== "boolean")
      throw new Error("Invalid acckaprodi value.");

    this._acckaprodi = acckaprodi;
  }

  get lulus() {
    return this._lulus;
  }

  set lulus(lulus) {
    if (typeof lulus !== "boolean") throw new Error("Invalid lulus value.");

    this._lulus = lulus;
  }

  get laporanSatu() {
    return this._laporanSatu;
  }

  set laporanSatu(laporanSatu) {
    if (!laporanSatu) throw new Error("Invalid laporanSatu value.");

    laporanSatu = laporanSatu.trim();
    if (laporanSatu === "") throw new Error("Invalid laporanSatu value.");

    this._laporanSatu = laporanSatu;
  }

  get laporanDua() {
    return this._laporanDua;
  }

  set laporanDua(laporanDua) {
    if (!laporanDua) throw new Error("Invalid laporanDua value.");

    laporanDua = laporanDua.trim();
    if (laporanDua === "") throw new Error("Invalid laporanDua value.");

    this._laporanDua = laporanDua;
  }

  get laporanTiga() {
    return this._laporanTiga;
  }

  set laporanTiga(laporanTiga) {
    if (!laporanTiga) throw new Error("Invalid laporanTiga value.");

    laporanTiga = laporanTiga.trim();
    if (laporanTiga === "") throw new Error("Invalid laporanTiga value.");

    this._laporanTiga = laporanTiga;
  }

  get komentarLaporanSatu() {
    return this._komentarLaporanSatu;
  }

  set komentarLaporanSatu(komentarLaporanSatu) {
    if (!komentarLaporanSatu)
      throw new Error("Invalid komentarLaporanSatu value.");

    komentarLaporanSatu = komentarLaporanSatu.trim();
    if (komentarLaporanSatu === "")
      throw new Error("Invalid komentarLaporanSatu value.");

    this._komentarLaporanSatu = komentarLaporanSatu;
  }

  get komentarLaporanDua() {
    return this._komentarLaporanDua;
  }

  set komentarLaporanDua(komentarLaporanDua) {
    if (!komentarLaporanDua)
      throw new Error("Invalid komentarLaporanDua value.");

    komentarLaporanDua = komentarLaporanDua.trim();
    if (komentarLaporanDua === "")
      throw new Error("Invalid komentarLaporanDua value.");

    this._komentarLaporanDua = komentarLaporanDua;
  }

  get komentarLaporanTiga() {
    return this._komentarLaporanTiga;
  }

  set komentarLaporanTiga(komentarLaporanTiga) {
    if (!komentarLaporanTiga)
      throw new Error("Invalid komentarLaporanTiga value.");

    komentarLaporanTiga = komentarLaporanTiga.trim();
    if (komentarLaporanTiga === "")
      throw new Error("Invalid komentarLaporanTiga value.");

    this._komentarLaporanTiga = komentarLaporanTiga;
  }

  get revisiSatu() {
    return this._revisiSatu;
  }

  set revisiSatu(revisiSatu) {
    if (!revisiSatu) throw new Error("Invalid revisiSatu value.");

    revisiSatu = revisiSatu.trim();
    if (revisiSatu === "") throw new Error("Invalid revisiSatu value.");

    this._revisiSatu = revisiSatu;
  }

  get revisiDua() {
    return this._revisiDua;
  }

  set revisiDua(revisiDua) {
    if (!revisiDua) throw new Error("Invalid revisiDua value.");

    revisiDua = revisiDua.trim();
    if (revisiDua === "") throw new Error("Invalid revisiDua value.");

    this._revisiDua = revisiDua;
  }

  get revisiTiga() {
    return this._revisiTiga;
  }

  set revisiTiga(revisiTiga) {
    if (!revisiTiga) throw new Error("Invalid revisiTiga value.");

    revisiTiga = revisiTiga.trim();
    if (revisiTiga === "") throw new Error("Invalid revisiTiga value.");

    this._revisiTiga = revisiTiga;
  }

  get finalProject() {
    return this._finalProject;
  }

  set finalProject(finalProject) {
    if (!finalProject) throw new Error("Invalid finalProject value.");

    finalProject = finalProject.trim();
    if (finalProject === "") throw new Error("Invalid finalProject value.");

    this._finalProject = finalProject;
  }

  async save() {
    const sql = `INSERT INTO kelompok (code, judul, nama, skema, dosen, ketua, anggota, accdospem, acckaprodi, lulus, laporanSatu, laporanDua, laporanTiga, komentarLaporanSatu, komentarLaporanDua, komentarLaporanTiga, revisiSatu, revisiDua, revisiTiga, finalProject) VALUES ("${
      this.code
    }", "${this.judul}", "${this.nama}", "${this.skema}", "${this.dosen}", "${
      this.ketua
    }", '${JSON.stringify(this.anggota)}', ${this.accdospem}, ${
      this.acckaprodi
    }, ${this.lulus}, "${this.laporanSatu}", "${this.laporanDua}", "${
      this.laporanTiga
    }", "${this.komentarLaporanSatu}", "${this.komentarLaporanDua}", "${
      this.komentarLaporanTiga
    }", "${this.revisiSatu}", "${this.revisiDua}", "${this.revisiTiga}", "${
      this.finalProject
    }")`;
    await pool.execute(sql);
  }

  static async find() {
    const sql = "SELECT * FROM kelompok";
    const [rows, fields] = await pool.execute(sql);

    return rows;
  }

  static async findById(code) {
    const sql = `SELECT * FROM kelompok WHERE code = "${code}"`;
    const [rows, fields] = await pool.execute(sql);

    return rows[0];
  }

  static async findByDospem(nomor) {
    const sql = `SELECT * FROM kelompok WHERE dosen = ${nomor}`;
    const [rows, fields] = await pool.execute(sql);

    return rows;
  }

  static async findByAccDospem(nilai) {
    if (nilai === null) {
      const sql = `SELECT * FROM kelompok WHERE accdospem IS NULL`;
      const [rows, fields] = await pool.execute(sql);
      return rows;
    } else {
      const sql = `SELECT * FROM kelompok WHERE accdospem = ?`;
      const [rows, fields] = await pool.execute(sql, [nilai]);
      return rows;
    }
  }

  static async findByAccKaprodi(nilai) {
    if (nilai === null) {
      const sql = `SELECT * FROM kelompok WHERE acckaprodi IS NULL`;
      const [rows, fields] = await pool.execute(sql);
      return rows;
    } else {
      const sql = `SELECT * FROM kelompok WHERE acckaprodi = ?`;
      const [rows, fields] = await pool.execute(sql, [nilai]);
      return rows;
    }
  }

  static async findByIdAndUpdate(code, options) {
    const sql = `UPDATE kelompok SET judul = "${options.judul}", nama = "${
      options.nama
    }", skema = "${options.skema}", dosen = "${options.dosen}", ketua = "${
      options.ketua
    }", anggota = '${JSON.stringify(options.anggota)}', accdospem = ${
      options.accdospem
    }, acckaprodi = ${options.acckaprodi}, lulus = ${
      options.lulus
    }, laporanSatu = "${options.laporanSatu}", laporanDua = "${
      options.laporanDua
    }", laporanTiga = "${options.laporanTiga}", komentarLaporanSatu = "${
      options.komentarLaporanSatu
    }", komentarLaporanDua = "${options.komentarLaporanDua}", komentarLaporanTiga = "${
      options.komentarLaporanTiga
    }", revisiSatu = "${options.revisiSatu}", revisiDua = "${
      options.revisiDua
    }", revisiTiga = "${options.revisiTiga}", finalProject = "${
      options.finalProject
    }" WHERE code = "${code}"`;
    await pool.execute(sql);
  }

  static async findByIdAndDelete(code) {
    const sql = `DELETE FROM kelompok WHERE code = "${code}"`;
    await pool.execute(sql);
  }
}

module.exports = Kelompok;
