import json
import os
from datetime import datetime
import tkinter as tk
from tkinter import ttk, simpledialog, messagebox
from openpyxl import Workbook, load_workbook
from openpyxl.styles import PatternFill

DATA_FILE = "dochazka_cache.json"
HISTORY_FILE = "dochazka_history.xlsx"
ROOMS_FILE = "rooms.json"
CHIPS_FILE = "chips.json"

# ---------- Default rooms ----------
def get_default_rooms():
    skip_rooms = {7, 25, 45}
    rooms = {str(i): [] for i in range(1, 61) if i not in skip_rooms}
    return rooms

# ---------- Rooms storage ----------
def load_rooms():
    if os.path.exists(ROOMS_FILE):
        with open(ROOMS_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return get_default_rooms()

def save_rooms(rooms_data):
    with open(ROOMS_FILE, "w", encoding="utf-8") as f:
        json.dump(rooms_data, f, indent=4, ensure_ascii=False)

rooms = load_rooms()

# ---------- RFID chips ----------
def load_chips():
    if os.path.exists(CHIPS_FILE):
        with open(CHIPS_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_chips(chips_data):
    with open(CHIPS_FILE, "w", encoding="utf-8") as f:
        json.dump(chips_data, f, indent=4, ensure_ascii=False)

chips = load_chips()

# ---------- Attendance storage ----------
def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_data(data):
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

# ---------- Excel history ----------
def save_history(record):
    red_fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
    green_fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")

    month_name = datetime.now().strftime("%m-%Y")

    if os.path.exists(HISTORY_FILE):
        wb = load_workbook(HISTORY_FILE)
    else:
        wb = Workbook()

    if month_name in wb.sheetnames:
        ws = wb[month_name]
    else:
        ws = wb.create_sheet(title=month_name)
        ws.append(["Jméno", "Stav", "Kam", "Čas", "Datum"])

    last_date = None
    if ws.max_row > 1:
        last_date = ws.cell(row=ws.max_row, column=5).value

    if last_date and last_date != record["date"]:
        ws.append(["", "", "", "", ""])

    ws.append([
        record["person"],
        record["status"],
        record["place"],
        record["time"],
        record["date"]
    ])

    row = ws.max_row
    fill = green_fill if record["status"] == "Přítomen" else red_fill

    for col in range(1, 6):
        ws.cell(row=row, column=col).fill = fill

    wb.save(HISTORY_FILE)

# ---------- App ----------
class App:
    def __init__(self, root):
        self.root = root
        self.root.title("Docházka")
        self.root.state("zoomed")

        self.data = load_data()

        # RFID buffer
        self.rfid_buffer = ""
        self.root.bind("<Key>", self.handle_rfid_input)

        self.create_ui()
        self.refresh()

    def create_ui(self):
        frame = ttk.Frame(self.root, padding=20)
        frame.pack(fill="both", expand=True)

        self.date_label = ttk.Label(frame, text="", font=("Arial", 20))
        self.date_label.pack(pady=10)

        self.stats_label = ttk.Label(frame, text="", font=("Arial", 14))
        self.stats_label.pack(pady=5)

        search_frame = ttk.Frame(frame)
        search_frame.pack(pady=5)

        ttk.Label(search_frame, text="Pokoj:").pack(side="left")
        self.search_var = tk.StringVar()
        ttk.Entry(search_frame, textvariable=self.search_var, width=10).pack(side="left", padx=5)
        ttk.Button(search_frame, text="Najít", command=self.search_room).pack(side="left")

        columns = ("Pokoj", "Jméno", "Stav", "Čas", "Kam")
        self.tree = ttk.Treeview(frame, columns=columns, show="headings")
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, anchor="center")
        self.tree.pack(fill="both", expand=True)

        self.tree.bind("<Double-1>", self.toggle_status)
        self.tree.bind("<Button-3>", self.show_menu)

        self.menu = tk.Menu(self.root, tearoff=0)
        self.menu.add_command(label="Upravit jméno", command=self.edit_name)
        self.menu.add_command(label="Přidat osobu", command=self.add_person)
        self.menu.add_separator()
        self.menu.add_command(label="Smazat osobu", command=self.delete_person)
        self.menu.add_separator()
        self.menu.add_command(label="Přiřadit čip", command=self.assign_chip)

        self.tree.tag_configure("in", background="#c8f7c5")
        self.tree.tag_configure("out", background="#f7c5c5")
        self.tree.tag_configure("separator", background="#d9d9d9")

        # ---------- Copyright ----------
        self.copyright_label = ttk.Label(
            frame,
            text="Autor se vzdává veškeré odpovědnosti za případnou ztrátu či poškození dat. Úpravy JSON souborů ručně nebo úpravy Excel souboru mohou vést ke ztrátě dat a provádíte je na vlastní riziko.",
            font=("Arial", 5),
            foreground="red",
            wraplength=800,
            justify="center"
        )
        self.copyright_label.pack(pady=(5,0))
            
        self.copyright_label2 = ttk.Label(
            frame,
            text="PCZ - 2026",
            font=("Arial", 4),
            foreground="black",
            wraplength=800,
            justify="center"
        )
        self.copyright_label2.pack(pady=(5,0))

    def handle_rfid_input(self, event):
        if event.keysym == "Return":
            chip_id = self.rfid_buffer.strip()
            self.rfid_buffer = ""
            if chip_id:
                self.process_chip(chip_id)
        else:
            self.rfid_buffer += event.char

    def process_chip(self, chip_id):
        if chip_id not in chips:
            messagebox.showwarning("Neznámý čip", f"Čip {chip_id} není přiřazen.")
            return

        person = chips[chip_id]

        current = self.data.get(person, {}).get("status", "Přítomen")
        now = datetime.now()

        if current == "Přítomen":
            place = simpledialog.askstring("Odchod", "Kam jde?")
            status = "Nepřítomen"
            place_val = place or "Neuvedeno"
        else:
            status = "Přítomen"
            place_val = "V budově"

        self.data[person] = {
            "status": status,
            "time": now.strftime("%H:%M:%S"),
            "date": now.strftime("%d.%m.%Y"),
            "place": place_val
        }

        save_data(self.data)
        save_history(self.data[person] | {"person": person})
        self.refresh()

    def refresh(self):
        self.tree.delete(*self.tree.get_children())

        today = datetime.now().strftime("%d.%m.%Y")
        self.date_label.config(text=f"Datum: {today}")

        present, absent = 0, 0

        for room in sorted(rooms.keys(), key=lambda x: int(x)):
            self.tree.insert("", "end", values=(f"--- Pokoj {room} ---", "", "", "", ""), tags=("separator",))
            for person in rooms[room]:
                info = self.data.get(person, {})
                status = info.get("status", "Přítomen")
                if status == "Přítomen":
                    present += 1
                else:
                    absent += 1
                self.tree.insert("", "end", values=(
                    room,
                    person,
                    status,
                    f"{info.get('time','-')} ({info.get('date','')})",
                    info.get("place", "-")
                ), tags=("in" if status == "Přítomen" else "out",))
        self.stats_label.config(text=f"Přítomní: {present} | Nepřítomní: {absent}")

    def search_room(self):
        target = self.search_var.get()
        for item in self.tree.get_children():
            if f"--- Pokoj {target} ---" in str(self.tree.item(item, "values")):
                self.tree.selection_set(item)
                self.tree.see(item)
                break

    def show_menu(self, event):
        self.selected_item = self.tree.identify_row(event.y)
        if self.selected_item:
            self.tree.selection_set(self.selected_item)
            self.menu.post(event.x_root, event.y_root)

    def assign_chip(self):
        values = self.tree.item(self.selected_item, "values")
        if "---" in values[0]:
            return

        person = values[1]

        chip_id = simpledialog.askstring("Čip", "Přilož čip (nebo zadej ID):")
        if not chip_id:
            return

        chips[chip_id] = person
        save_chips(chips)

        messagebox.showinfo("Hotovo", f"Čip {chip_id} přiřazen k {person}")

    def edit_name(self):
        values = self.tree.item(self.selected_item, "values")
        if "---" in values[0]:
            return
        old = values[1]
        new = simpledialog.askstring("Jméno", "Nové jméno:", initialvalue=old)
        if new:
            room = values[0]
            rooms[room].remove(old)
            rooms[room].append(new)
            self.data[new] = self.data.pop(old, {})
            save_rooms(rooms)
            save_data(self.data)
            self.refresh()

    def add_person(self):
        values = self.tree.item(self.selected_item, "values")
        if "---" not in values[0]:
            return
        room = values[0].replace("--- Pokoj ", "").replace(" ---", "")
        name = simpledialog.askstring("Nový člověk", "Jméno:")
        if name:
            rooms[room].append(name)
            save_rooms(rooms)
            self.refresh()

    def delete_person(self):
        values = self.tree.item(self.selected_item, "values")
        if "---" in values[0]:
            return
        person = values[1]
        room = values[0]
        confirm = messagebox.askyesno("Potvrzení", f"Opravdu smazat {person}?")
        if confirm:
            if person in rooms[room]:
                rooms[room].remove(person)
            if person in self.data:
                del self.data[person]
            save_rooms(rooms)
            save_data(self.data)
            self.refresh()

    def toggle_status(self, event):
        item = self.tree.selection()[0]
        values = self.tree.item(item, "values")
        if "---" in values[0]:
            return
        person = values[1]
        current = self.data.get(person, {}).get("status", "Přítomen")
        now = datetime.now()
        if current == "Přítomen":
            place = simpledialog.askstring("Odchod", "Kam jde?")
            status = "Nepřítomen"
            place_val = place or "Neuvedeno"
        else:
            status = "Přítomen"
            place_val = "V budově"
        self.data[person] = {
            "status": status,
            "time": now.strftime("%H:%M:%S"),
            "date": now.strftime("%d.%m.%Y"),
            "place": place_val
        }
        save_data(self.data)
        save_history(self.data[person] | {"person": person})
        self.refresh()

# ---------- Run ----------
if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()