import os, datetime, json, calendar
import customtkinter as ctk
from tkinter import filedialog, messagebox
from PIL import Image, ImageDraw, ImageFont

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
BULAN_MASEHI = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]
BULAN_HIJRIAH = ["Muharam", "Safar", "Rabiulawal", "Rabiulakhir", "Jumadilawal", "Jumadilakhir", "Rajab", "Syakban", "Ramadan", "Syawal", "Zulkaidah", "Zulhijah"]

# ---> SILAKAN COPAS HIJRI_DB LENGKAP DI SINI <---
HIJRI_DB = {
    1447: [["Muharam", "", "26-Jun-2025", 30], ["Safar", "", "26-Jul-2025", 29], ["Rabiulawal", "", "24-Aug-2025", 30], ["Rabiulakhir", "", "23-Sep-2025", 30], ["Jumadilawal", "", "23-Oct-2025", 29], ["Jumadilakhir", "", "21-Nov-2025", 30], ["Rajab", "", "21-Dec-2025", 30], ["Syakban", "", "20-Jan-2026", 29], ["Ramadan", "", "18-Feb-2026", 30], ["Syawal", "", "20-Mar-2026", 29], ["Zulkaidah", "", "18-Apr-2026", 30], ["Zulhijah", "", "18-May-2026", 29]]
}
try:
    DB_JSON_PATH = os.path.join(BASE_DIR, "db_hijriah.json")
    if os.path.exists(DB_JSON_PATH):
        with open(DB_JSON_PATH, "r", encoding="utf-8") as f:
            HIJRI_DB.update({int(k): v for k, v in json.load(f).items()})
except Exception: pass

class HijriConverter:
    @staticmethod
    def parse_date(date_str):
        try:
            m = {"Jan":1, "Feb":2, "Mar":3, "Apr":4, "May":5, "Jun":6, "Jul":7, "Aug":8, "Sep":9, "Oct":10, "Nov":11, "Dec":12}
            parts = date_str.split('-')
            return datetime.date(int(parts[2]), m.get(parts[1], 1), int(parts[0]))
        except: return None
    @staticmethod
    def get_hijri_date(today):
        for year, months in HIJRI_DB.items():
            for m_data in months:
                start = HijriConverter.parse_date(m_data[2])
                if start and start <= today < start + datetime.timedelta(days=m_data[3]):
                    return f"{(today - start).days + 1} {m_data[0]} {year} H"
        return "N/A"

class Menu27App(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Kalender Masehi Berjalan (Modul 27)")
        self.geometry("1100x750")
        ctk.set_appearance_mode("Dark")
        
        now = datetime.date.today()
        self.cal_m_year = now.year
        self.cal_m_month = now.month
        self.setup_ui()
        self.render_kalmasehi()

    def setup_ui(self):
        self.sidebar = ctk.CTkFrame(self, width=250)
        self.sidebar.pack(side="left", fill="y", padx=10, pady=10)
        
        ctk.CTkLabel(self.sidebar, text="KALENDER MASEHI", font=("Segoe UI", 16, "bold"), text_color="#00E5FF").pack(pady=20)
        
        self.combo_bln = ctk.CTkComboBox(self.sidebar, values=BULAN_MASEHI)
        self.combo_bln.set(BULAN_MASEHI[self.cal_m_month-1])
        self.combo_bln.pack(pady=10, padx=10, fill="x")
        
        self.entry_thn = ctk.CTkEntry(self.sidebar, justify="center")
        self.entry_thn.insert(0, str(self.cal_m_year))
        self.entry_thn.pack(pady=10, padx=10, fill="x")
        
        ctk.CTkButton(self.sidebar, text="🔍 Terapkan", command=self.apply_kalmasehi).pack(pady=10, fill="x", padx=10)
        
        self.main_frame = ctk.CTkFrame(self, fg_color="transparent")
        self.main_frame.pack(side="right", fill="both", expand=True, padx=10, pady=10)
        
        header_cal = ctk.CTkFrame(self.main_frame, fg_color="#101018", corner_radius=8)
        header_cal.pack(fill="x", pady=(0, 10))

        ctk.CTkButton(header_cal, text="◀ Seb", width=80, command=self.prev_month).pack(side="left", padx=10, pady=10)
        self.lbl_title = ctk.CTkLabel(header_cal, text="", font=("Segoe UI", 22, "bold"), text_color="#00E5FF", justify="center")
        self.lbl_title.pack(side="left", expand=True)
        ctk.CTkButton(header_cal, text="Ber ▶", width=80, command=self.next_month).pack(side="right", padx=10, pady=10)

        frame_export = ctk.CTkFrame(self.main_frame, fg_color="transparent")
        frame_export.pack(fill="x", pady=(0, 10))
        ctk.CTkButton(frame_export, text="📄 Cetak PDF", fg_color="#D32F2F", command=lambda: self.export_kalender("pdf")).pack(side="right", padx=5)
        ctk.CTkButton(frame_export, text="📸 Simpan PNG", fg_color="#F57C00", command=lambda: self.export_kalender("png")).pack(side="right", padx=5)

        self.grid_cal_frame = ctk.CTkFrame(self.main_frame, fg_color="#050510", corner_radius=10)
        self.grid_cal_frame.pack(fill="both", expand=True)

    def apply_kalmasehi(self):
        try:
            self.cal_m_year = int(self.entry_thn.get())
            self.cal_m_month = BULAN_MASEHI.index(self.combo_bln.get()) + 1
            self.render_kalmasehi()
        except ValueError: messagebox.showerror("Error", "Tahun harus angka!")

    def prev_month(self):
        self.cal_m_month -= 1
        if self.cal_m_month < 1:
            self.cal_m_month = 12; self.cal_m_year -= 1
        self.render_kalmasehi()

    def next_month(self):
        self.cal_m_month += 1
        if self.cal_m_month > 12:
            self.cal_m_month = 1; self.cal_m_year += 1
        self.render_kalmasehi()

    def _get_islamic_event(self, h_day, h_month, weekday):
        color = None
        if (h_month == 10 and h_day == 1) or (h_month == 12 and h_day == 10) or (h_month == 12 and h_day in [11, 12, 13]):
            return "#FF5252" # Haram Puasa
        if h_month == 1 and h_day in [9, 10]: color = "#00E676"
        if h_month == 12 and h_day in [8, 9]: color = "#00E676"
        if h_month == 9: color = "#8BC34A"
        if h_day in [13, 14, 15] and h_month != 9: color = "#00B0FF"
        if weekday in [0, 3] and h_month != 9 and not color: color = "#FFA000"
        return color

    def render_kalmasehi(self):
        for widget in self.grid_cal_frame.winfo_children(): widget.destroy()

        y, m = self.cal_m_year, self.cal_m_month
        _, jumlah_hari = calendar.monthrange(y, m)
        start_date = datetime.date(y, m, 1)
        
        self.lbl_title.configure(text=f"{BULAN_MASEHI[m-1]} {y}")
        self.combo_bln.set(BULAN_MASEHI[m-1])
        self.entry_thn.delete(0, 'end'); self.entry_thn.insert(0, str(y))

        days_header = ["Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Ahad"]
        for col, day_name in enumerate(days_header):
            color_bg = "#D84315" if col == 6 else "#E65100"
            ctk.CTkLabel(self.grid_cal_frame, text=day_name, font=("Segoe UI", 14, "bold"), fg_color=color_bg, corner_radius=5).grid(row=0, column=col, padx=3, pady=5, sticky="nsew")

        offset = start_date.weekday()
        row, col = 1, offset
        curr_g = start_date

        for m_day in range(1, jumlah_hari + 1):
            cell = ctk.CTkFrame(self.grid_cal_frame, fg_color="#1E1E1E", corner_radius=8, border_width=1, border_color="#424242")
            cell.grid(row=row, column=col, padx=4, pady=4, sticky="nsew")

            color_masehi = "#FF5252" if col == 6 else "#00E5FF" 
            ctk.CTkLabel(cell, text=str(m_day), font=("Consolas", 32, "bold"), text_color=color_masehi).pack(expand=True)

            h_str = HijriConverter.get_hijri_date(curr_g)
            parts = h_str.split()
            h_str_short = f"{parts[0]} {parts[1][:3]} {parts[2]} H" if len(parts) >= 4 else h_str
            
            color_h = "#FFD54F"
            if len(parts) >= 4:
                try:
                    ev_color = self._get_islamic_event(int(parts[0]), BULAN_HIJRIAH.index(parts[1]) + 1, curr_g.weekday())
                    if ev_color: color_h = ev_color
                except: pass
                
            ctk.CTkLabel(cell, text=h_str_short, font=("Segoe UI", 11), text_color=color_h).pack(side="bottom", anchor="e", padx=8, pady=3)

            col += 1
            if col > 6: col, row = 0, row + 1
            curr_g += datetime.timedelta(days=1)

        for i in range(7): self.grid_cal_frame.grid_columnconfigure(i, weight=1)
        for i in range(7): self.grid_cal_frame.grid_rowconfigure(i, weight=1)

    def _generate_image(self):
        img = Image.new("RGB", (1400, 1000), "#0A0A10")
        draw = ImageDraw.Draw(img)
        try:
            f_title = ImageFont.truetype("arialbd.ttf", 46)
            f_sub = ImageFont.truetype("arial.ttf", 26)
            f_day = ImageFont.truetype("arialbd.ttf", 22)
            f_m = ImageFont.truetype("arialbd.ttf", 64)
            f_h = ImageFont.truetype("arial.ttf", 16)
        except:
            f_title = f_sub = f_day = f_m = f_h = ImageFont.load_default()

        y, m = self.cal_m_year, self.cal_m_month
        _, jumlah_hari = calendar.monthrange(y, m)
        start_date = datetime.date(y, m, 1)

        draw.text((700, 60), f"Kalender Masehi: {BULAN_MASEHI[m-1]} {y}", font=f_title, fill="#00E5FF", anchor="mm")
        
        start_x, start_y, cell_w, cell_h = 50, 180, 185, 120
        days_header = ["Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Ahad"]
        for i, d_name in enumerate(days_header):
            x0, y0, x1, y1 = start_x + i * cell_w, start_y, start_x + i * cell_w + cell_w - 10, start_y + 45
            color_bg = "#D84315" if i == 6 else "#E65100" 
            draw.rectangle([x0, y0, x1, y1], fill=color_bg, outline="#E65100", width=2)
            draw.text(((x0+x1)/2, (y0+y1)/2), d_name, font=f_day, fill="white", anchor="mm")

        row, col = 0, start_date.weekday()
        curr_g = start_date
        grid_y_start = start_y + 60

        for m_day in range(1, jumlah_hari + 1):
            x0, y0 = start_x + col * cell_w, grid_y_start + row * cell_h
            x1, y1 = x0 + cell_w - 10, y0 + cell_h - 10
            draw.rectangle([x0, y0, x1, y1], fill="#1E1E1E", outline="#424242", width=2)

            color_masehi = "#FF5252" if col == 6 else "#00E5FF"
            draw.text(((x0+x1)/2, y0 + 40), str(m_day), font=f_m, fill=color_masehi, anchor="mm")

            h_str = HijriConverter.get_hijri_date(curr_g)
            parts = h_str.split()
            h_str_short = f"{parts[0]} {parts[1][:3]} {parts[2]} H" if len(parts) >= 4 else h_str
            
            color_h = "#FFD54F"
            if len(parts) >= 4:
                try:
                    ev_color = self._get_islamic_event(int(parts[0]), BULAN_HIJRIAH.index(parts[1]) + 1, curr_g.weekday())
                    if ev_color: 
                        color_h = ev_color
                        draw.ellipse([x1-25, y0+15, x1-15, y0+25], fill=color_h)
                except: pass
                
            draw.text((x1 - 10, y1 - 15), h_str_short, font=f_h, fill=color_h, anchor="rm")

            col += 1
            if col > 6: col, row = 0, row + 1
            curr_g += datetime.timedelta(days=1)
            
        draw.text((700, 960), "KHGT Times Engine V7.2 - By Kasmui", font=f_sub, fill="#555555", anchor="mm")
        return img

    def export_kalender(self, fmt):
        img = self._generate_image()
        fname = filedialog.asksaveasfilename(initialfile=f"Kalender_Masehi_{BULAN_MASEHI[self.cal_m_month-1]}_{self.cal_m_year}.{fmt}", defaultextension=f".{fmt}")
        if fname:
            try:
                img.save(fname, fmt.upper(), resolution=150.0 if fmt=="pdf" else None)
                messagebox.showinfo("Sukses", f"Berhasil disimpan: {fname}")
            except Exception as e: messagebox.showerror("Error", str(e))

if __name__ == "__main__":
    app = Menu27App()
    app.mainloop()