from pathlib import Path
from datetime import datetime

from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.table import WD_ALIGN_VERTICAL, WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Inches, Pt, RGBColor


OUT = Path(r"C:\xampp\htdocs\audit\dokumentasi\Checklist_Modul_Sistem_Dashboard_Audit_MAINPP.docx")

BLUE = RGBColor(0, 102, 255)
DARK = RGBColor(15, 23, 42)
MUTED = RGBColor(71, 85, 105)
GREEN = RGBColor(22, 163, 74)
RED = RGBColor(220, 38, 38)
AMBER = RGBColor(180, 83, 9)
LIGHT_BLUE = "EFF6FF"
LIGHT_GREEN = "ECFDF5"
LIGHT_RED = "FEF2F2"
LIGHT_AMBER = "FFFBEB"
GRID = "D8E3F0"


def set_cell_shading(cell, fill):
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = OxmlElement("w:shd")
    shd.set(qn("w:fill"), fill)
    tc_pr.append(shd)


def set_cell_border(cell, color=GRID):
    tc = cell._tc
    tc_pr = tc.get_or_add_tcPr()
    tc_borders = tc_pr.first_child_found_in("w:tcBorders")
    if tc_borders is None:
        tc_borders = OxmlElement("w:tcBorders")
        tc_pr.append(tc_borders)
    for edge in ("top", "left", "bottom", "right"):
        tag = f"w:{edge}"
        element = tc_borders.find(qn(tag))
        if element is None:
            element = OxmlElement(tag)
            tc_borders.append(element)
        element.set(qn("w:val"), "single")
        element.set(qn("w:sz"), "6")
        element.set(qn("w:space"), "0")
        element.set(qn("w:color"), color)


def set_cell_margins(cell, top=90, start=120, bottom=90, end=120):
    tc = cell._tc
    tc_pr = tc.get_or_add_tcPr()
    tc_mar = tc_pr.first_child_found_in("w:tcMar")
    if tc_mar is None:
        tc_mar = OxmlElement("w:tcMar")
        tc_pr.append(tc_mar)
    for m, v in {"top": top, "start": start, "bottom": bottom, "end": end}.items():
        node = tc_mar.find(qn(f"w:{m}"))
        if node is None:
            node = OxmlElement(f"w:{m}")
            tc_mar.append(node)
        node.set(qn("w:w"), str(v))
        node.set(qn("w:type"), "dxa")


def set_cell_text(cell, text, bold=False, color=DARK, size=9.5, align=None):
    cell.text = ""
    p = cell.paragraphs[0]
    if align:
        p.alignment = align
    run = p.add_run(str(text))
    run.bold = bold
    run.font.name = "Arial"
    run.font.size = Pt(size)
    run.font.color.rgb = color
    cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
    set_cell_margins(cell)
    set_cell_border(cell)


def style_doc(doc):
    sec = doc.sections[0]
    sec.top_margin = Inches(0.7)
    sec.bottom_margin = Inches(0.7)
    sec.left_margin = Inches(0.75)
    sec.right_margin = Inches(0.75)
    for style_name in ["Normal", "Title", "Subtitle", "Heading 1", "Heading 2", "Heading 3"]:
        style = doc.styles[style_name]
        style.font.name = "Arial"
    normal = doc.styles["Normal"]
    normal.font.size = Pt(10.5)
    normal.font.color.rgb = DARK


def add_header_footer(doc):
    for sec in doc.sections:
        header = sec.header
        p = header.paragraphs[0]
        p.text = "Checklist Modul Sistem Dashboard Audit MAINPP"
        p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        for r in p.runs:
            r.font.name = "Arial"
            r.font.size = Pt(8)
            r.font.color.rgb = MUTED
        footer = sec.footer
        p = footer.paragraphs[0]
        p.text = "Majlis Agama Islam Negeri Pulau Pinang | Checklist Sistem"
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        for r in p.runs:
            r.font.name = "Arial"
            r.font.size = Pt(8)
            r.font.color.rgb = MUTED


def heading(doc, text, level=1):
    p = doc.add_heading(text, level=level)
    for run in p.runs:
        run.font.name = "Arial"
        run.font.color.rgb = BLUE if level <= 2 else DARK
    return p


def para(doc, text, bold=False, color=DARK):
    p = doc.add_paragraph()
    p.paragraph_format.space_after = Pt(5)
    p.paragraph_format.line_spacing = 1.08
    r = p.add_run(text)
    r.bold = bold
    r.font.name = "Arial"
    r.font.size = Pt(10.5)
    r.font.color.rgb = color
    return p


def add_status_table(doc):
    rows = [
        ("Ada", "Fungsi sudah wujud dalam sistem dan boleh diuji.", "Hijau"),
        ("Belum Ada", "Fungsi belum dibangunkan atau belum tersedia dalam sistem semasa.", "Merah"),
        ("Perlu Semak", "Fungsi wujud, tetapi perlu disahkan semasa UAT atau perlu penambahbaikan kecil.", "Kuning"),
    ]
    tbl = doc.add_table(rows=1, cols=3)
    tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
    headers = ["Status", "Maksud", "Kod Warna"]
    for i, h in enumerate(headers):
        set_cell_text(tbl.cell(0, i), h, True, BLUE, 9.5)
        set_cell_shading(tbl.cell(0, i), LIGHT_BLUE)
    for status, desc, color in rows:
        cells = tbl.add_row().cells
        c = GREEN if status == "Ada" else RED if status == "Belum Ada" else AMBER
        set_cell_text(cells[0], status, True, c)
        set_cell_text(cells[1], desc)
        set_cell_text(cells[2], color, True, c)
        if status == "Ada":
            set_cell_shading(cells[0], LIGHT_GREEN)
        elif status == "Belum Ada":
            set_cell_shading(cells[0], LIGHT_RED)
        else:
            set_cell_shading(cells[0], LIGHT_AMBER)
    doc.add_paragraph()


def add_checklist_table(doc, module, rows):
    heading(doc, module, 2)
    tbl = doc.add_table(rows=1, cols=5)
    tbl.alignment = WD_TABLE_ALIGNMENT.LEFT
    widths = [0.35, 3.0, 0.7, 0.9, 3.0]
    headers = ["Bil", "Item / Fungsi", "Ada", "Belum Ada", "Catatan"]
    for i, h in enumerate(headers):
        cell = tbl.cell(0, i)
        set_cell_text(cell, h, True, BLUE, 9.2, WD_ALIGN_PARAGRAPH.CENTER if i in [0, 2, 3] else None)
        set_cell_shading(cell, LIGHT_BLUE)
        cell.width = Inches(widths[i])
    for item in rows:
        bil, name, exists, note = item
        cells = tbl.add_row().cells
        set_cell_text(cells[0], bil, True, MUTED, 9.0, WD_ALIGN_PARAGRAPH.CENTER)
        set_cell_text(cells[1], name, False, DARK, 9.2)
        set_cell_text(cells[2], "Ya" if exists else "", True, GREEN, 9.2, WD_ALIGN_PARAGRAPH.CENTER)
        set_cell_text(cells[3], "" if exists else "Ya", True, RED, 9.2, WD_ALIGN_PARAGRAPH.CENTER)
        set_cell_text(cells[4], note, False, MUTED, 9.0)
        if exists:
            set_cell_shading(cells[2], LIGHT_GREEN)
        else:
            set_cell_shading(cells[3], LIGHT_RED)
    doc.add_paragraph()


def add_summary_table(doc, modules):
    heading(doc, "Ringkasan Status Modul", 1)
    tbl = doc.add_table(rows=1, cols=4)
    headers = ["Modul", "Bil. Fungsi Ada", "Bil. Fungsi Belum Ada", "Kesimpulan"]
    for i, h in enumerate(headers):
        set_cell_text(tbl.cell(0, i), h, True, BLUE, 9.2)
        set_cell_shading(tbl.cell(0, i), LIGHT_BLUE)
    for module, rows in modules:
        ada = sum(1 for r in rows if r[2])
        tiada = sum(1 for r in rows if not r[2])
        cells = tbl.add_row().cells
        set_cell_text(cells[0], module)
        set_cell_text(cells[1], ada, True, GREEN, 9.2, WD_ALIGN_PARAGRAPH.CENTER)
        set_cell_text(cells[2], tiada, True, RED if tiada else GREEN, 9.2, WD_ALIGN_PARAGRAPH.CENTER)
        conclusion = "Lengkap untuk fungsi asas." if tiada == 0 else "Ada fungsi cadangan / belum dibangunkan."
        set_cell_text(cells[3], conclusion, False, MUTED, 9.0)
    doc.add_paragraph()


modules = [
    ("1. Login, Register dan Kawalan Sesi", [
        ("1.1", "Halaman login sistem", True, "Wujud melalui login.php dan login_process.php."),
        ("1.2", "Halaman register pengguna", True, "Wujud melalui register.php/register_process.php dan daftar_pengguna.php."),
        ("1.3", "Kawalan session expire / keepalive", True, "Wujud melalui keepalive.php dan layout session modal."),
        ("1.4", "Logout pengguna", True, "Wujud melalui logout.php."),
    ]),
    ("2. Forgot Password", [
        ("2.1", "Masukkan emel dan nombor kad pengenalan", True, "Wujud pada forgot_password.php."),
        ("2.2", "Semakan emel dan IC dalam database", True, "Wujud pada proses_forgot_password.php."),
        ("2.3", "Hantar verification code melalui email SMTP", True, "Wujud mengikut konfigurasi SMTP sistem."),
        ("2.4", "Halaman verify reset code", True, "Wujud pada verify_reset_code.php."),
        ("2.5", "Halaman tetapan kata laluan baharu", True, "Wujud pada reset_password.php."),
    ]),
    ("3. Dashboard", [
        ("3.1", "Kad statistik untuk Pentadbir Sistem/Admin Audit", True, "Jumlah audit, isu selesai dan isu belum selesai."),
        ("3.2", "Dashboard khusus untuk Pengguna Biasa mengikut bahagian", True, "Statistik difilter mengikut bahagian pengguna."),
        ("3.3", "Carta palang isu selesai dan belum selesai mengikut bahagian/unit", True, "Wujud pada dashboard.php."),
        ("3.4", "Carta pai pecahan status isu", True, "Wujud pada dashboard.php."),
        ("3.5", "Carta bar isu belum selesai mengikut bahagian", True, "Wujud pada dashboard.php."),
        ("3.6", "Bahagian lain boleh mengisi sub maklum balas 1.1, 1.2 dan 1.3 terus dari dashboard", False, "Cadangan fungsi baharu. Belum ada dalam sistem, jadi tidak ditanda sebagai tersedia."),
        ("3.7", "Paparan tracking sub maklum balas 1.1, 1.2, 1.3 dan tambahan 1.4 pada dashboard", False, "Belum ada. Sesuai ditambah selepas struktur sub-item dibuat dalam database."),
    ]),
    ("4. Daftar Maklumat Audit", [
        ("4.1", "Daftar perkara audit", True, "Wujud pada daftar_maklumat_audit.php."),
        ("4.2", "Tetapkan tarikh mula dan tarikh akhir audit", True, "Wujud dan digunakan untuk kawalan tempoh maklum balas."),
        ("4.3", "Pilih Tindakan Bahagian", True, "Sebelum ini Ditugaskan Kepada, kini digunakan sebagai Tindakan Bahagian."),
        ("4.4", "Muat naik lampiran audit", True, "Wujud melalui proses daftar maklumat audit."),
        ("4.5", "Tambah sub maklum balas 1.1, 1.2 dan 1.3 semasa daftar audit", False, "Cadangan fungsi baharu. Belum ada dalam sistem semasa."),
        ("4.6", "Tambah sub maklum balas tambahan seperti 1.4 secara dinamik", False, "Cadangan fungsi baharu. Perlu reka bentuk jadual sub-item dahulu."),
        ("4.7", "Tetapkan sub maklum balas kepada bahagian tertentu", False, "Belum ada. Boleh dikaitkan dengan audit_form_assignments jika dibangunkan."),
    ]),
    ("5. Senarai Maklumat Audit", [
        ("5.1", "Paparan senarai audit", True, "Wujud pada senarai_maklumat_audit.php."),
        ("5.2", "Filter perkara, bahagian, tempoh dan tarikh", True, "Wujud pada senarai maklumat audit."),
        ("5.3", "Ringkasan perkara audit dengan Lihat Lagi", True, "Wujud untuk teks panjang melebihi had baris."),
        ("5.4", "Butang edit, delete dan view mengikut capaian", True, "Wujud dan tertakluk kepada permission."),
        ("5.5", "Kolum Status dibuang", True, "Sudah disesuaikan mengikut permintaan semasa."),
    ]),
    ("6. Maklum Balas Audit", [
        ("6.1", "Borang maklum balas audit", True, "Wujud pada maklum_balas_audit.php."),
        ("6.2", "Textarea maklum balas diperbesarkan", True, "Sudah disesuaikan."),
        ("6.3", "Sekatan isi sebelum tarikh mula", True, "Wujud mengikut kawalan tempoh audit."),
        ("6.4", "Sekatan kemaskini selepas tarikh akhir", True, "Wujud mengikut kawalan tempoh audit."),
        ("6.5", "Tarikh hantar update apabila maklum balas dikemaskini", True, "Wujud melalui penggunaan updated_at."),
        ("6.6", "Field role dibuang daripada borang", True, "Sudah disesuaikan."),
        ("6.7", "Sub maklum balas 1.1, 1.2, 1.3 mengikut item audit", False, "Belum ada. Perlu jadual sub feedback dan paparan input berulang."),
    ]),
    ("7. Senarai Maklum Balas Audit", [
        ("7.1", "Paparan senarai maklum balas", True, "Wujud pada senarai_maklum_balas_audit.php."),
        ("7.2", "Kolum Status dibuang", True, "Sudah disesuaikan."),
        ("7.3", "View detail maklum balas", True, "Wujud melalui detail_maklum_balas_audit.php."),
        ("7.4", "Edit dan delete dibuang di detail maklum balas audit", True, "Sudah disesuaikan."),
        ("7.5", "Paparan progress sub maklum balas 1.1, 1.2, 1.3", False, "Belum ada kerana sub-item maklum balas belum dibangunkan."),
    ]),
    ("8. Catatan Audit dan Kelulusan Audit", [
        ("8.1", "Admin Audit boleh memberi catatan audit", True, "Wujud melalui proses_catatan_audit.php."),
        ("8.2", "Notifikasi catatan audit kepada bahagian berkaitan", True, "Wujud mengikut permintaan semasa."),
        ("8.3", "Kelulusan audit mengikut bahagian", True, "Wujud pada dashboard dan proses_kelulusan_audit.php."),
        ("8.4", "Status Selesai Audit", True, "Istilah Lulus DiAudit telah diubah kepada Selesai Audit."),
    ]),
    ("9. Notifikasi", [
        ("9.1", "Ikon notifikasi di header", True, "Wujud dalam layout header."),
        ("9.2", "Halaman notifikasi", True, "Wujud pada notifications.php."),
        ("9.3", "Tandakan notifikasi sebagai dibaca", True, "Wujud pada mark_notification_read.php/notifications_action.php."),
        ("9.4", "Notifikasi tugasan audit", True, "Wujud untuk audit yang ditugaskan kepada bahagian."),
        ("9.5", "Notifikasi email selain forgot password", False, "Belum jelas sebagai fungsi umum. Boleh jadi cadangan masa hadapan."),
    ]),
    ("10. Pengguna dan Pendaftaran", [
        ("10.1", "Daftar pengguna", True, "Wujud pada daftar_pengguna.php."),
        ("10.2", "Pengurusan pendaftaran", True, "Wujud pada pengurusan_pendaftaran.php."),
        ("10.3", "Senarai pengguna", True, "Wujud pada senarai_pengguna.php."),
        ("10.4", "Edit pengguna", True, "Wujud pada edit_pengguna.php."),
        ("10.5", "Admin tidak boleh ubah role Pentadbir Sistem", True, "Sudah dibuat sebagai kawalan role dilindungi."),
        ("10.6", "Label User Biasa diubah kepada Pengguna Biasa", True, "Sudah disesuaikan."),
    ]),
    ("11. Capaian Bahagian dan Capaian Pengguna", [
        ("11.1", "Capaian Bahagian", True, "Wujud pada capaian_pengguna.php dan proses_capaian_pengguna.php."),
        ("11.2", "Capaian Pengguna individu", True, "Wujud melalui proses_capaian_user.php."),
        ("11.3", "Link capaian pengguna kepada capaian bahagian", True, "Capaian pengguna boleh digunakan sebagai override kepada bahagian."),
        ("11.4", "Permission Create, Read, Update, Delete", True, "Wujud mengikut modul yang sesuai."),
        ("11.5", "Permission Rollback", True, "Wujud dalam matriks capaian."),
        ("11.6", "Rollback capaian", True, "Wujud melalui proses_rollback_capaian_pengguna.php."),
    ]),
    ("12. Transaksi Log Pengguna dan Profile", [
        ("12.1", "Transaksi log pengguna", True, "Wujud pada transaksi_log_pengguna.php."),
        ("12.2", "Profile pengguna", True, "Wujud pada profile_pengguna.php."),
        ("12.3", "Kemaskini profile pengguna", True, "Wujud pada proses_profile_pengguna.php."),
        ("12.4", "Export log ke Excel/PDF", False, "Belum ada. Sesuai sebagai cadangan laporan masa hadapan."),
    ]),
]


doc = Document()
style_doc(doc)
add_header_footer(doc)

title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = title.add_run("CHECKLIST MODUL SISTEM DASHBOARD AUDIT MAINPP")
r.bold = True
r.font.name = "Arial"
r.font.size = Pt(20)
r.font.color.rgb = BLUE

subtitle = doc.add_paragraph()
subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = subtitle.add_run("Semakan fungsi sedia ada, fungsi belum ada dan cadangan penambahbaikan")
r.font.name = "Arial"
r.font.size = Pt(11)
r.font.color.rgb = MUTED

meta = doc.add_table(rows=4, cols=2)
meta.alignment = WD_TABLE_ALIGNMENT.CENTER
meta_rows = [
    ("Nama Sistem", "Dashboard Audit MAINPP"),
    ("Organisasi", "Majlis Agama Islam Negeri Pulau Pinang"),
    ("Tarikh Dokumen", datetime.now().strftime("%d/%m/%Y")),
    ("Tujuan", "Checklist UAT dan semakan pembangunan modul sistem audit"),
]
for i, (k, v) in enumerate(meta_rows):
    set_cell_text(meta.cell(i, 0), k, True, BLUE, 9.5)
    set_cell_text(meta.cell(i, 1), v, False, DARK, 9.5)
    set_cell_shading(meta.cell(i, 0), LIGHT_BLUE)
doc.add_paragraph()

heading(doc, "Tujuan Dokumen", 1)
para(doc, "Dokumen ini disediakan sebagai checklist semakan modul untuk Sistem Dashboard Audit MAINPP. Checklist ini membezakan fungsi yang sudah wujud dalam sistem dengan fungsi yang belum ada atau masih menjadi cadangan pembangunan.")
para(doc, "Item yang ditanda pada kolum Ada bermaksud fungsi tersebut telah dikenal pasti wujud dalam struktur sistem semasa. Item yang ditanda pada kolum Belum Ada bermaksud fungsi tersebut belum dibangunkan, belum tersedia atau perlu direka bentuk sebelum boleh digunakan.")
para(doc, "Fungsi berkaitan sub maklum balas 1.1, 1.2, 1.3 dan tambahan 1.4 dimasukkan sebagai cadangan khusus seperti diminta. Item tersebut sengaja tidak ditanda sebagai Ada kerana fungsi itu belum wujud dalam sistem semasa.")

add_status_table(doc)
add_summary_table(doc, modules)

doc.add_section(WD_SECTION.NEW_PAGE)
heading(doc, "Checklist Terperinci Mengikut Modul", 1)
for module, rows in modules:
    add_checklist_table(doc, module, rows)

heading(doc, "Cadangan Fungsi Baharu: Sub Maklum Balas Audit 1.1, 1.2, 1.3 dan 1.4", 1)
para(doc, "Fungsi ini dicadangkan supaya semasa daftar maklumat audit, Admin Audit boleh mencipta beberapa sub item maklum balas seperti 1.1, 1.2 dan 1.3. Jika perlu, Admin Audit boleh menambah item seterusnya seperti 1.4 secara dinamik. Setiap sub item boleh digunakan sebagai pecahan isu atau pecahan tindakan yang lebih terperinci.")
para(doc, "Pada dashboard atau halaman tindakan bahagian, pengguna bahagian lain boleh mengisi maklum balas berdasarkan sub item tersebut. Contohnya, Bahagian Teknologi Maklumat boleh mengisi jawapan bagi 1.1, 1.2 dan 1.3 secara berasingan. Ini akan memudahkan Admin Audit melihat isu mana yang sudah dijawab dan isu mana yang masih belum lengkap.")
para(doc, "Namun fungsi ini belum ada dalam sistem semasa. Oleh itu, dalam checklist dokumen ini, item tersebut diletakkan sebagai Belum Ada. Untuk membangunkan fungsi ini, sistem perlu menambah struktur database baharu seperti audit_feedback_items atau audit_sub_feedbacks, menambah paparan input berulang di borang daftar audit, dan menambah paparan maklum balas berasingan mengikut sub item pada dashboard serta halaman maklum balas audit.")

heading(doc, "Keutamaan Pembangunan Seterusnya", 1)
priority_rows = [
    ("Tinggi", "Sub maklum balas 1.1, 1.2, 1.3 dan 1.4", "Fungsi ini memberi pecahan tindakan lebih jelas kepada bahagian."),
    ("Sederhana", "Paparan progress sub item di dashboard", "Boleh dibuat selepas struktur sub item siap."),
    ("Sederhana", "Notifikasi email umum selain forgot password", "Berguna untuk tugasan audit dan catatan audit."),
    ("Rendah", "Export transaksi log ke Excel/PDF", "Sesuai untuk laporan pentadbiran."),
]
tbl = doc.add_table(rows=1, cols=3)
for i, h in enumerate(["Keutamaan", "Fungsi", "Sebab"]):
    set_cell_text(tbl.cell(0, i), h, True, BLUE, 9.2)
    set_cell_shading(tbl.cell(0, i), LIGHT_BLUE)
for row in priority_rows:
    cells = tbl.add_row().cells
    set_cell_text(cells[0], row[0], True, AMBER if row[0] == "Sederhana" else RED if row[0] == "Tinggi" else MUTED)
    set_cell_text(cells[1], row[1])
    set_cell_text(cells[2], row[2])

doc.save(OUT)
print(OUT)
