"""Skema MySQL Atlas Histo.

Dua lapis:
  SKEMA        tabel dasar yang dibutuhkan app (dibuat bila belum ada)
  KOLOM_BARU   kolom yang lahir belakangan, ditambahkan ke DB lama tanpa
               menghapus data (dicek lewat information_schema)

Semua langkah idempotent: aman dijalankan setiap app start.
"""

from __future__ import annotations

import mysql.connector
from mysql.connector import Error as MySQLError

from konfigurasi import DB_CFG

SKEMA = (
    """
    CREATE TABLE IF NOT EXISTS gambar (
        id INT(11) NOT NULL AUTO_INCREMENT,
        judul VARCHAR(255) NOT NULL,
        kategori VARCHAR(100) DEFAULT NULL,
        deskripsi TEXT DEFAULT NULL,
        file_gambar VARCHAR(500) DEFAULT NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY idx_kategori (kategori)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS pengguna (
        id INT(11) NOT NULL AUTO_INCREMENT,
        nama VARCHAR(120) NOT NULL,
        pengguna VARCHAR(60) NOT NULL,
        email VARCHAR(160) DEFAULT NULL,
        sandi_hash VARCHAR(255) NOT NULL,
        peran ENUM('admin','dosen','mahasiswa') NOT NULL DEFAULT 'mahasiswa',
        aktif TINYINT(1) NOT NULL DEFAULT 1,
        ganti_sandi TINYINT(1) NOT NULL DEFAULT 0,
        dibuat_pada TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        masuk_terakhir DATETIME NULL,
        PRIMARY KEY (id),
        UNIQUE KEY uq_pengguna (pengguna)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS kelas (
        id INT(11) NOT NULL AUTO_INCREMENT,
        nama VARCHAR(160) NOT NULL,
        kode_gabung VARCHAR(8) NOT NULL,
        dosen_id INT(11) DEFAULT NULL,
        deskripsi TEXT DEFAULT NULL,
        aktif TINYINT(1) NOT NULL DEFAULT 1,
        dibuat_pada TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY uq_kode (kode_gabung),
        KEY idx_dosen_kelas (dosen_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS kelas_anggota (
        id INT(11) NOT NULL AUTO_INCREMENT,
        kelas_id INT(11) NOT NULL,
        pengguna_id INT(11) NOT NULL,
        tanggal_gabung TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY uq_anggota (kelas_id, pengguna_id),
        KEY idx_pengguna_anggota (pengguna_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS kunjungan (
        id INT(11) NOT NULL AUTO_INCREMENT,
        pengguna_id INT(11) NOT NULL,
        gambar_id INT(11) NOT NULL,
        pertama TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        terakhir DATETIME NULL,
        jumlah INT(11) NOT NULL DEFAULT 1,
        PRIMARY KEY (id),
        UNIQUE KEY uq_kunjungan (pengguna_id, gambar_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS belajar (
        id INT(11) NOT NULL AUTO_INCREMENT,
        pengguna_id INT(11) NOT NULL,
        gambar_id INT(11) NOT NULL,
        ditandai_pada TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY uq_belajar (pengguna_id, gambar_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS ujian (
        id INT(11) NOT NULL AUTO_INCREMENT,
        kelas_id INT(11) NOT NULL,
        dosen_id INT(11) NOT NULL,
        judul VARCHAR(200) NOT NULL,
        petunjuk TEXT DEFAULT NULL,
        mulai DATETIME NULL,
        tutup DATETIME NULL,
        durasi_menit INT(11) DEFAULT NULL,
        acak TINYINT(1) NOT NULL DEFAULT 1,
        tampilkan_kunci TINYINT(1) NOT NULL DEFAULT 0,
        status ENUM('draf','terbit','tutup') NOT NULL DEFAULT 'draf',
        dibuat_pada TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY idx_kelas_ujian (kelas_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS soal (
        id INT(11) NOT NULL AUTO_INCREMENT,
        ujian_id INT(11) NOT NULL,
        gambar_id INT(11) NOT NULL,
        tipe ENUM('isian_tunjuk','pilihan_ganda') NOT NULL DEFAULT 'isian_tunjuk',
        pertanyaan TEXT NOT NULL,
        x_pos DECIMAL(5,1) NOT NULL DEFAULT 50,
        y_pos DECIMAL(5,1) NOT NULL DEFAULT 50,
        kunci_teks VARCHAR(255) DEFAULT NULL,
        sinonim TEXT DEFAULT NULL,
        pilihan TEXT DEFAULT NULL,
        jawaban_pg INT(11) DEFAULT NULL,
        skor INT(11) NOT NULL DEFAULT 10,
        pembahasan TEXT DEFAULT NULL,
        urutan INT(11) NOT NULL DEFAULT 0,
        PRIMARY KEY (id),
        KEY idx_ujian_soal (ujian_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS pengerjaan (
        id INT(11) NOT NULL AUTO_INCREMENT,
        ujian_id INT(11) NOT NULL,
        pengguna_id INT(11) NOT NULL,
        mulai DATETIME NOT NULL,
        batas DATETIME DEFAULT NULL,
        selesai DATETIME DEFAULT NULL,
        nilai DECIMAL(6,2) DEFAULT NULL,
        status ENUM('jalan','selesai','dinilai') NOT NULL DEFAULT 'jalan',
        PRIMARY KEY (id),
        UNIQUE KEY uq_pengerjaan (ujian_id, pengguna_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS jawaban (
        id INT(11) NOT NULL AUTO_INCREMENT,
        pengerjaan_id INT(11) NOT NULL,
        soal_id INT(11) NOT NULL,
        teks VARCHAR(500) DEFAULT NULL,
        pilihan INT(11) DEFAULT NULL,
        benar TINYINT(1) DEFAULT NULL,
        nilai DECIMAL(6,2) DEFAULT NULL,
        ditinjau_oleh INT(11) DEFAULT NULL,
        ditinjau_pada DATETIME DEFAULT NULL,
        dibuat_pada TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY uq_jawaban (pengerjaan_id, soal_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
    """
    CREATE TABLE IF NOT EXISTS anotasi (
        id INT(11) NOT NULL AUTO_INCREMENT,
        gambar_id INT(11) NOT NULL,
        label VARCHAR(100) NOT NULL,
        keterangan TEXT DEFAULT NULL,
        x_pos INT(11) DEFAULT 0,
        y_pos INT(11) DEFAULT 0,
        tipe VARCHAR(10) NOT NULL DEFAULT 'titik',
        titik MEDIUMTEXT DEFAULT NULL,
        PRIMARY KEY (id),
        KEY idx_gambar (gambar_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    """,
)

# (tabel, kolom, definisi) — urutan penting hanya untuk keterbacaan.
KOLOM_BARU = [
    ("anotasi", "tipe", "VARCHAR(10) NOT NULL DEFAULT 'titik'"),
    ("anotasi", "titik", "MEDIUMTEXT DEFAULT NULL"),
    ("gambar", "dosen_id", "INT(11) NULL"),
    ("gambar", "publik", "TINYINT(1) NOT NULL DEFAULT 1"),
    ("gambar", "aktif", "TINYINT(1) NOT NULL DEFAULT 1"),
    ("gambar", "perbesaran_total", "INT(11) NULL"),
    ("gambar", "objektif", "VARCHAR(10) NULL"),
    ("gambar", "okuler", "INT(11) NULL"),
    ("gambar", "um_per_px", "DECIMAL(10,5) NULL"),
    ("gambar", "skala_bar_um", "INT(11) NULL"),
    ("gambar", "skala_bar_px", "INT(11) NULL"),
    ("gambar", "kalibrasi_pada", "DATETIME NULL"),
    ("gambar", "file_proxy", "VARCHAR(500) NULL"),
    ("gambar", "lebar_px", "INT(11) NULL"),
    ("gambar", "tinggi_px", "INT(11) NULL"),
]


def siapkan_skema() -> None:
    """Buat tabel bila belum ada dan tambahkan kolom susulan. Diam kalau DB mati."""
    try:
        koneksi = mysql.connector.connect(**DB_CFG)
        cur = koneksi.cursor()
        for perintah in SKEMA:
            cur.execute(perintah)
        for tabel, kolom, definisi in KOLOM_BARU:
            cur.execute(
                "SELECT COUNT(*) FROM information_schema.columns "
                "WHERE table_schema = DATABASE() AND table_name = %s AND column_name = %s",
                (tabel, kolom),
            )
            if not cur.fetchone()[0]:
                cur.execute(f"ALTER TABLE {tabel} ADD COLUMN {kolom} {definisi}")
        koneksi.commit()
        cur.close()
        koneksi.close()
    except MySQLError as exc:  # DB mati saat start: jangan gagalkan app
        print(f"[atlas-histo] skema dilewati: {exc}", flush=True)
