"""
Precondition tab — Component merge, time alignment, and trim/splice operations.
"""

import logging
import threading
import tkinter as tk
from tkinter import ttk, filedialog, messagebox

from rshaketools.gui.helpers import labeled_entry, section_frame

logger = logging.getLogger("rshaketools")


class PreconditionTab(ttk.Frame):
    def __init__(self, parent, app):
        super().__init__(parent)
        self.app = app
        self._build()

    def _build(self):
        canvas = tk.Canvas(self, highlightthickness=0)
        scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
        self.inner = ttk.Frame(canvas)
        self.inner.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
        canvas.create_window((0, 0), window=self.inner, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # ── Section 1: Merge Components ─────────────────────────────────────
        frm1 = section_frame(self.inner, "🔀  Merge Components (> 3 traces)")
        self.mc_input = self._file_row(frm1, "Input:", 0, mode="open")
        self.mc_output = self._file_row(frm1, "Output:", 1, mode="save", default="merged_comps.mseed")
        ttk.Button(frm1, text="  ▶  Merge  ", command=self._do_merge_comps).grid(
            row=2, column=0, columnspan=3, pady=(12, 4), sticky="e"
        )

        # ── Section 2: Align Times ──────────────────────────────────────────
        frm2 = section_frame(self.inner, "⏱️  Align Times")
        self.at_input = self._file_row(frm2, "Input:", 0, mode="open")
        self.at_output = self._file_row(frm2, "Output:", 1, mode="save", default="aligned.mseed")
        ttk.Button(frm2, text="  ▶  Align  ", command=self._do_align).grid(
            row=2, column=0, columnspan=3, pady=(12, 4), sticky="e"
        )

        # ── Section 3: Trim & Splice ────────────────────────────────────────
        frm3 = section_frame(self.inner, "✂️  Trim & Splice")
        self.ts_input = self._file_row(frm3, "Input:", 0, mode="open")
        self.ts_output = self._file_row(frm3, "Output:", 1, mode="save", default="trimmed.mseed")
        self.ts_cut_start = labeled_entry(frm3, "Cut start (UTC):", "2023-01-11T08:27:31", row=2)
        self.ts_cut_end = labeled_entry(frm3, "Cut end (UTC):", "2023-01-11T08:27:51", row=3)
        ttk.Button(frm3, text="  ▶  Trim  ", command=self._do_trim).grid(
            row=4, column=0, columnspan=3, pady=(12, 4), sticky="e"
        )

    # ── Helpers ─────────────────────────────────────────────────────────────
    def _file_row(self, parent, label, row, mode="open", default=""):
        ttk.Label(parent, text=label, font=("Helvetica", 10)).grid(
            row=row, column=0, sticky="w", padx=(0, 8), pady=3
        )
        entry = ttk.Entry(parent, width=36, font=("Menlo", 10))
        if default:
            entry.insert(0, default)
        entry.grid(row=row, column=1, sticky="ew", pady=3)

        def _browse():
            if mode == "open":
                path = filedialog.askopenfilename(
                    filetypes=[("MiniSEED", "*.mseed"), ("All files", "*.*")]
                )
            else:
                path = filedialog.asksaveasfilename(
                    defaultextension=".mseed",
                    filetypes=[("MiniSEED", "*.mseed"), ("All files", "*.*")],
                )
            if path:
                entry.delete(0, tk.END)
                entry.insert(0, path)

        ttk.Button(parent, text="Browse …", command=_browse).grid(
            row=row, column=2, padx=(4, 0), sticky="w"
        )
        return entry

    # ── Actions ─────────────────────────────────────────────────────────────
    def _do_merge_comps(self):
        from rshaketools.precondition import merge_components
        inp = self.mc_input.get().strip()
        out = self.mc_output.get().strip()
        if not inp or not out:
            messagebox.showwarning("Validation", "Please specify input and output files.")
            return
        logger.info("Merging components from %s …", inp)

        def _run():
            try:
                st = merge_components(inp, out)
                logger.info("Component merge complete — %d trace(s)", len(st))
                self.app.after(0, lambda: messagebox.showinfo(
                    "Complete", f"Result: {len(st)} trace(s) → {out}"))
            except Exception as exc:
                logger.error("Merge components failed: %s", exc)
                self.app.after(0, lambda: messagebox.showerror("Error", str(exc)))

        threading.Thread(target=_run, daemon=True).start()

    def _do_align(self):
        from rshaketools.precondition import align_times
        inp = self.at_input.get().strip()
        out = self.at_output.get().strip()
        if not inp or not out:
            messagebox.showwarning("Validation", "Please specify input and output files.")
            return
        logger.info("Aligning times for %s …", inp)

        def _run():
            try:
                st = align_times(inp, out)
                logger.info("Time alignment complete — %d trace(s)", len(st))
                self.app.after(0, lambda: messagebox.showinfo(
                    "Complete", f"Aligned {len(st)} trace(s) → {out}"))
            except Exception as exc:
                logger.error("Align times failed: %s", exc)
                self.app.after(0, lambda: messagebox.showerror("Error", str(exc)))

        threading.Thread(target=_run, daemon=True).start()

    def _do_trim(self):
        from rshaketools.precondition import trim_and_splice
        inp = self.ts_input.get().strip()
        out = self.ts_output.get().strip()
        cs = self.ts_cut_start.get().strip()
        ce = self.ts_cut_end.get().strip()
        if not all([inp, out, cs, ce]):
            messagebox.showwarning("Validation", "Please fill in all Trim fields.")
            return
        logger.info("Trimming %s (cut %s → %s) …", inp, cs, ce)

        def _run():
            try:
                st = trim_and_splice(inp, out, cs, ce)
                logger.info("Trim & splice complete — %d trace(s)", len(st))
                self.app.after(0, lambda: messagebox.showinfo(
                    "Complete", f"Trimmed {len(st)} trace(s) → {out}"))
            except Exception as exc:
                logger.error("Trim failed: %s", exc)
                self.app.after(0, lambda: messagebox.showerror("Error", str(exc)))

        threading.Thread(target=_run, daemon=True).start()

    def apply_theme(self, c):
        pass
