# markdownconverter/gui/editor.py

import tkinter as tk
from tkinter import messagebox
import ttkbootstrap as tb
from tkinter.scrolledtext import ScrolledText
from tkhtmlview import HTMLScrolledText
import markdown as MarkdownParser


class EditorWindow(tb.Toplevel):
    """
    A Toplevel window that provides a side-by-side Markdown editor
    and HTML preview with synchronized scrolling.
    """

    def __init__(self, parent, file_path):
        super().__init__(master=parent, title=f"Editing: {file_path}")
        self.geometry("1200x800")
        self.file_path = file_path

        self.md_parser = MarkdownParser.Markdown(extensions=["fenced_code", "tables"])

        self._setup_widgets()

        # Set the custom scroll command
        self.editor_text.vbar.config(command=self._on_editor_scroll)

        if not self._load_file():
            return

        self.editor_text.bind("<KeyRelease>", self._update_preview)

    def _setup_widgets(self):
        """Creates and arranges the widgets for the editor."""
        paned_window = tb.PanedWindow(self, orient=tk.HORIZONTAL)
        paned_window.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        editor_frame = tb.Frame(paned_window)
        tb.Label(editor_frame, text="Markdown Editor").pack(anchor="w", pady=(0, 5))
        self.editor_text = ScrolledText(
            editor_frame, wrap=tk.WORD, width=60, font=("Courier New", 10)
        )
        self.editor_text.pack(fill=tk.BOTH, expand=True)
        paned_window.add(editor_frame, weight=1)

        preview_frame = tb.Frame(paned_window)
        tb.Label(preview_frame, text="Live Preview").pack(anchor="w", pady=(0, 5))
        self.preview_widget = HTMLScrolledText(preview_frame, background="white")
        self.preview_widget.pack(fill=tk.BOTH, expand=True)
        paned_window.add(preview_frame, weight=1)

        button_frame = tb.Frame(self)
        button_frame.pack(fill=tk.X, padx=10, pady=5)

        tb.Button(
            button_frame,
            text="Save & Close",
            command=self._save_and_close,
            bootstyle="success",
        ).pack(side=tk.RIGHT, padx=5)

        tb.Button(
            button_frame, text="Cancel", command=self.destroy, bootstyle="secondary"
        ).pack(side=tk.RIGHT)

    def _on_editor_scroll(self, *args):
        """
        This method is set as the command for the editor's scrollbar.
        It scrolls the editor text and syncs the preview.
        """
        # Scroll the editor widget itself
        self.editor_text.yview(*args)

        # Get the new position
        scroll_position_fraction = self.editor_text.yview()[0]

        # --- CORREZIONE: Forza l'aggiornamento del widget di anteprima ---
        # This ensures the preview widget knows its full size before we try to scroll it.
        self.preview_widget.update_idletasks()

        if hasattr(self.preview_widget, "html_label") and hasattr(
            self.preview_widget.html_label, "_w"
        ):
            self.preview_widget.html_label._w.yview_moveto(scroll_position_fraction)

    def _load_file(self):
        """
        Loads the content of the file into the editor.
        Returns True on success, False on failure.
        """
        try:
            with open(self.file_path, "r", encoding="utf-8") as f:
                content = f.read()
            self.editor_text.delete("1.0", tk.END)
            self.editor_text.insert("1.0", content)
            self._update_preview()
            return True
        except Exception as e:
            messagebox.showerror(
                title="Error Loading File",
                message=f"Could not load the file:\n{e}",
            )
            self.destroy()
            return False

    def _update_preview(self, event=None):
        """Updates the HTML preview with the current editor content."""
        md_text = self.editor_text.get("1.0", tk.END)
        self.md_parser.reset()
        html_text = self.md_parser.convert(md_text)
        self.preview_widget.set_html(html_text)

        # --- CORREZIONE: Sincronizza sempre la vista dopo un aggiornamento ---
        self._on_editor_scroll("moveto", self.editor_text.yview()[0])

    def _save_and_close(self):
        """Saves the editor content back to the file and closes the window."""
        try:
            content = self.editor_text.get("1.0", tk.END).strip()
            with open(self.file_path, "w", encoding="utf-8") as f:
                f.write(content)
            self.destroy()
        except Exception as e:
            messagebox.showerror(
                title="Error Saving File",
                message=f"Could not save the file:\n{e}",
            )
