#!/usr/bin/python3
import gi, json, os
from datetime import datetime
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

NOTES_FILE = os.path.expanduser('~/.local/share/voice_notes.json')
os.makedirs(os.path.dirname(NOTES_FILE), exist_ok=True)

def load_notes():
    try:
        with open(NOTES_FILE) as f: return json.load(f)
    except Exception: return []

def save_notes(notes):
    with open(NOTES_FILE, 'w') as f: json.dump(notes, f, indent=2)

class App(Gtk.Window):
    def __init__(self):
        super().__init__(title='Voice Notes')
        self.set_default_size(640, 480)
        self.notes = load_notes()
        hpaned = Gtk.Paned(); self.add(hpaned)
        # left: list
        left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4)
        left.set_margin_top(6); left.set_margin_bottom(6)
        left.set_margin_start(6); left.set_margin_end(6)
        left.add(Gtk.Label(label='Notes', xalign=0))
        sw = Gtk.ScrolledWindow(); sw.set_size_request(200, -1)
        self.store = Gtk.ListStore(str, str)  # title, idx
        self.tv = Gtk.TreeView(model=self.store)
        col = Gtk.TreeViewColumn('Title', Gtk.CellRendererText(), text=0)
        self.tv.append_column(col)
        self.tv.get_selection().connect('changed', self.on_select)
        sw.add(self.tv)
        left.pack_start(sw, True, True, 0)
        del_btn = Gtk.Button(label='Delete')
        del_btn.connect('clicked', self.delete_note)
        left.pack_start(del_btn, False, False, 0)
        hpaned.add1(left)
        # right: editor
        right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        right.set_margin_top(6); right.set_margin_bottom(6)
        right.set_margin_start(6); right.set_margin_end(6)
        right.add(Gtk.Label(label='Title:', xalign=0))
        self.title_entry = Gtk.Entry()
        right.pack_start(self.title_entry, False, False, 0)
        right.add(Gtk.Label(label='Note:', xalign=0))
        sw2 = Gtk.ScrolledWindow()
        self.body_tv = Gtk.TextView(); self.body_tv.set_wrap_mode(Gtk.WrapMode.WORD)
        sw2.add(self.body_tv)
        right.pack_start(sw2, True, True, 0)
        self.date_lbl = Gtk.Label(label='', xalign=0)
        right.pack_start(self.date_lbl, False, False, 0)
        hb = Gtk.Box(spacing=6)
        save_btn = Gtk.Button(label='Save Note')
        save_btn.connect('clicked', self.save_note)
        hb.pack_start(save_btn, True, True, 0)
        new_btn = Gtk.Button(label='New Note')
        new_btn.connect('clicked', self.new_note)
        hb.pack_start(new_btn, True, True, 0)
        right.pack_start(hb, False, False, 0)
        hpaned.add2(right)
        self.current_idx = None
        self.refresh_list()
    def refresh_list(self):
        self.store.clear()
        for i, n in enumerate(self.notes):
            self.store.append([n.get('title', 'Untitled'), str(i)])
    def on_select(self, sel):
        model, it = sel.get_selected()
        if it:
            idx = int(model[it][1])
            self.current_idx = idx
            n = self.notes[idx]
            self.title_entry.set_text(n.get('title',''))
            self.body_tv.get_buffer().set_text(n.get('body',''))
            self.date_lbl.set_text(f'Created: {n.get("date","")}')
    def save_note(self, *_):
        title = self.title_entry.get_text().strip() or 'Untitled'
        buf = self.body_tv.get_buffer()
        body = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False)
        date = datetime.now().strftime('%Y-%m-%d %H:%M')
        if self.current_idx is not None:
            self.notes[self.current_idx] = {'title':title,'body':body,'date':date}
        else:
            self.notes.append({'title':title,'body':body,'date':date})
        save_notes(self.notes)
        self.refresh_list()
    def new_note(self, *_):
        self.current_idx = None
        self.title_entry.set_text('')
        self.body_tv.get_buffer().set_text('')
        self.date_lbl.set_text('')
    def delete_note(self, *_):
        if self.current_idx is not None:
            self.notes.pop(self.current_idx)
            save_notes(self.notes)
            self.current_idx = None
            self.title_entry.set_text('')
            self.body_tv.get_buffer().set_text('')
            self.refresh_list()

win = App()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
