import os
import json
import datetime
import tkinter as tk
from tkinter import messagebox
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

# --- フォントの設定 (日本語対応) ---
def get_japanese_font():
    if os.name == 'nt':
        return "MS-Gothic", "C:\\Windows\\Fonts\\msgothic.ttc"
    else:
        return "HeiseiMin-W3", None

FONT_NAME, FONT_PATH = get_japanese_font()
if FONT_PATH and os.path.exists(FONT_PATH):
    try:
        pdfmetrics.registerFont(TTFont(FONT_NAME, FONT_PATH))
    except:
        FONT_NAME = "Helvetica"

DISPLAY_WIDTH = 295
DISPLAY_HEIGHT = 510

class WeeklyNotebookApp:
    def __init__(self, root):
        self.root = root
        self.root.title("システム手帳")
        self.root.geometry("660x670")
        self.root.resizable(False, False)

        self.current_base_date = datetime.date.today()
        self.data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
        os.makedirs(self.data_dir, exist_ok=True)

        self.day_names_en = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
        self.day_names_ja = ["月", "火", "水", "木", "金", "土", "日"]

        self.entries = {}
        self.label_widgets = {}

        self.setup_gui()
        self.update_week_data()

    def calculate_week_dates(self):
        self.monday_date = self.current_base_date - datetime.timedelta(days=self.current_base_date.weekday())
        self.week_dates = [self.monday_date + datetime.timedelta(days=i) for i in range(7)]

        year, week_num, _ = self.monday_date.isocalendar()
        self.json_filename = f"{year}_w{week_num:02d}.json"
        self.json_path = os.path.join(self.data_dir, self.json_filename)

        self.day_keys = []
        for d, name_ja in zip(self.week_dates, self.day_names_ja):
            self.day_keys.append(f"{d.strftime('%Y-%m-%d')}_{name_ja}")
        self.day_keys.append("MEMO")

    def update_week_data(self):
        self.calculate_week_dates()

        # エラー箇所を修正：self.week_dates[0] に変更して月曜日の日付を取得するようにしました
        info_text = f"【対象週】 {self.week_dates[0].strftime('%Y/%m/%d')} 〜 {self.week_dates[-1].strftime('%Y/%m/%d')}"
        self.info_label.config(text=info_text)

        for global_idx, key in enumerate(self.day_keys):
            lbl_widget = self.label_widgets[global_idx]
            if key == "MEMO":
                lbl_widget.config(text="FREE MEMO")
            else:
                date_str, day_ja = key.split("_")
                label_text = f"{date_str} ({day_ja}) {self.day_names_en[global_idx]}"
                lbl_widget.config(text=label_text)

        self.loaded_data = self.load_json_data()

        for key, txt_widget in self.entries.items():
            txt_widget.delete("1.0", tk.END)

        old_entries = list(self.entries.values())
        self.entries = {}
        for global_idx, key in enumerate(self.day_keys):
            txt_widget = old_entries[global_idx]
            self.entries[key] = txt_widget
            if key in self.loaded_data:
                txt_widget.insert("1.0", self.loaded_data[key])

    def load_json_data(self):
        if os.path.exists(self.json_path):
            try:
                with open(self.json_path, "r", encoding="utf-8") as f:
                    return json.load(f)
            except Exception as e:
                print(f"Read Error: {e}")
        return {}

    def change_week(self, weeks_delta):
        self.save_to_json(silent=True)
        self.current_base_date += datetime.timedelta(weeks=weeks_delta)
        self.update_week_data()

    def setup_gui(self):
        nav_frame = tk.Frame(self.root)
        nav_frame.pack(pady=10)

        prev_btn = tk.Button(nav_frame, text="◀ 前の週", font=("Helvetica", 10, "bold"), padx=10, command=lambda: self.change_week(-1))
        prev_btn.grid(row=0, column=0, padx=20)

        self.info_label = tk.Label(nav_frame, text="", font=("Helvetica", 12, "bold"), fg="#444444")
        self.info_label.grid(row=0, column=1, padx=20)

        next_btn = tk.Button(nav_frame, text="次の週 ▶", font=("Helvetica", 10, "bold"), padx=10, command=lambda: self.change_week(1))
        next_btn.grid(row=0, column=2, padx=20)

        main_frame = tk.Frame(self.root)
        main_frame.pack(pady=5)

        left_frame = tk.LabelFrame(main_frame, text="左ページ", padx=5, pady=5)
        left_frame.grid(row=0, column=0, padx=10)
        self.create_page_inputs(left_frame, range(4), is_left=True)

        right_frame = tk.LabelFrame(main_frame, text="右ページ", padx=5, pady=5)
        right_frame.grid(row=0, column=1, padx=10)
        self.create_page_inputs(right_frame, range(4, 8), is_left=False)

        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=10)

        save_btn = tk.Button(btn_frame, text="JSONデータを上書き保存", font=("Helvetica", 11, "bold"), bg="#2196F3", fg="white", padx=15, pady=5, command=lambda: self.save_to_json(silent=False))
        save_btn.grid(row=0, column=0, padx=10)

        pdf_btn = tk.Button(btn_frame, text="印刷用PDFを出力", font=("Helvetica", 11, "bold"), bg="#4CAF50", fg="white", padx=15, pady=5, command=self.save_to_pdf)
        pdf_btn.grid(row=0, column=1, padx=10)

    def create_page_inputs(self, parent, idx_range, is_left):
        canvas_bg = tk.Canvas(parent, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, bg="#FCFCF9", highlightthickness=1, highlightbackground="#CCCCCC")
        canvas_bg.pack()

        hole_x = 10 if is_left else DISPLAY_WIDTH - 18
        for i in range(6):
            canvas_bg.create_oval(hole_x, 60 + (i * 70), hole_x+8, 60 + (i * 70)+8, fill="#888888", outline="")

        box_height = 115
        start_y = 15

        for local_idx, global_idx in enumerate(idx_range):
            y_pos = start_y + (local_idx * box_height)
            x_pos = 35 if is_left else 15

            lbl = tk.Label(canvas_bg, font=("Helvetica", 9, "bold"), bg="#FCFCF9")
            canvas_bg.create_window(x_pos, y_pos, window=lbl, anchor="nw")
            self.label_widgets[global_idx] = lbl

            txt = tk.Text(canvas_bg, font=("Helvetica", 10), width=30, height=4, bd=1, relief="solid")
            canvas_bg.create_window(x_pos, y_pos + 20, window=txt, anchor="nw")

            self.entries[global_idx] = txt

    def gather_current_data(self):
        current_data = {}
        for key, txt_widget in self.entries.items():
            current_data[key] = txt_widget.get("1.0", "end-1c")
        return current_data

    def save_to_json(self, silent=False):
        data = self.gather_current_data()
        if not any(data.values()) and not os.path.exists(self.json_path):
            return
        try:
            with open(self.json_path, "w", encoding="utf-8") as f:
                json.dump(data, f, ensure_ascii=False, indent=4)
            if not silent:
                messagebox.showinfo("保存成功", f"データを保存しました。\ndata/{self.json_filename}")
            self.loaded_data = data
        except Exception as e:
            if not silent:
                messagebox.showerror("エラー", f"保存失敗:\n{e}")

    def save_to_pdf(self):
        filename = f"weekly_{self.monday_date.strftime('%Y%m%d')}.pdf"
        width, height = 95 * mm, 170 * mm
        c = canvas.Canvas(filename, pagesize=(width, height))
        data = self.gather_current_data()

        self.draw_pdf_page(c, width, height, self.day_keys[:4], is_left=True, data=data)
        c.showPage()
        self.draw_pdf_page(c, width, height, self.day_keys[4:], is_left=False, data=data)
        c.showPage()

        c.save()
        messagebox.showinfo("PDF出力成功", f"PDFを作成しました。\n{filename}")

    def draw_pdf_page(self, c, width, height, keys, is_left, data):
        margin_left = 15 * mm if is_left else 5 * mm
        margin_right = 5 * mm if is_left else 15 * mm
        content_width = width - margin_left - margin_right
        box_height_pdf = (height - 20 * mm) / 4

        for i, key in enumerate(keys):
            y_pos = height - 15 * mm - (i * box_height_pdf)

            c.setLineWidth(0.3)
            c.setStrokeColorRGB(0.6, 0.6, 0.6)
            c.rect(margin_left, y_pos - box_height_pdf, content_width, box_height_pdf)

            if key == "MEMO":
                label_text = "MEMO"
            else:
                date_str, day_ja = key.split("_")
                label_text = f"{date_str} ({day_ja})"

            c.setFont(FONT_NAME, 9)
            c.setFillColorRGB(0.2, 0.2, 0.2)
            c.drawString(margin_left + 3 * mm, y_pos - 5 * mm, label_text)

            text_content = data.get(key, "")
            raw_lines = text_content.split("\n")
            formatted_lines = []

            for r_line in raw_lines:
                while len(r_line) > 24:
                    formatted_lines.append(r_line[:24])
                    r_line = r_line[24:]
                formatted_lines.append(r_line)

            c.setFont(FONT_NAME, 8)
            for idx, line in enumerate(formatted_lines[:5]):
                c.drawString(margin_left + 5 * mm, y_pos - 10 * mm - (idx * 3.5 * mm), line)

if __name__ == "__main__":
    root = tk.Tk()
    app = WeeklyNotebookApp(root)
    root.mainloop()
