import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from tkinter.scrolledtext import ScrolledText
import pandas as pd
import os
from PIL import Image, ImageTk
import docx

# Set relative file paths for portability across different systems
base_path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_path, "table.xlsx")
reference_path = os.path.join(base_path, "reference.docx")
fig_dir = os.path.join(base_path, "Fig")
front_image_path = os.path.join(base_path, "Front.jpg")

# Verify required files exist
if not os.path.exists(file_path):
    messagebox.showerror("Error", f"Excel file '{file_path}' not found.")
    exit()

# Load Excel data
try:
    df = pd.read_excel(file_path)
    df.columns = df.columns.str.strip()
except Exception as e:
    messagebox.showerror("Error", f"Failed to read Excel file: {e}")
    exit()

# Create main window
root = tk.Tk()
root.title("Tectono-Sedimentary Basins Program")
root.geometry("800x600")

# Welcome message
intro_frame = tk.Frame(root)
intro_frame.pack(pady=10)
welcome_label = tk.Label(intro_frame, text="Welcome to the Tectono-sedimentary Basin Program (TSBP)!", font=("Arial", 16, "bold"))
welcome_label.pack()

# Additional program information
program_info_label = tk.Label(intro_frame, text=(
    "This program is created by M.R. Sheikholeslami, Research Institute for Earth Sciences, Tehran, Iran,\n"
    "in collaboration with Copilot. It classifies tectonic basins and presents their key characteristics."
), font=("Arial", 12), justify="center")
program_info_label.pack(pady=5)

# Display introductory image
if os.path.exists(front_image_path):
    image = Image.open(front_image_path).resize((700, 370), Image.Resampling.LANCZOS)
    img_tk = ImageTk.PhotoImage(image)
    img_label = tk.Label(root, image=img_tk)
    img_label.image = img_tk
    img_label.pack(pady=10)
else:
    messagebox.showwarning("Warning", "Introductory image not found!")

# Selection menus
selection_frame = tk.Frame(root)
selection_frame.pack(pady=10)
tk.Label(selection_frame, text="Select Tectonic Setting:", font=("Arial", 12)).grid(row=0, column=0, padx=10)

# Dropdown for tectonic setting
tectonic_setting_var = tk.StringVar()
tectonic_settings = df['Tectonic setting'].unique().tolist()
tectonic_dropdown = ttk.Combobox(selection_frame, textvariable=tectonic_setting_var, values=tectonic_settings, width=30)
tectonic_dropdown.grid(row=0, column=1)

# Dropdown for basin type
tk.Label(selection_frame, text="Select Basin Type:", font=("Arial", 12)).grid(row=1, column=0, padx=10)
basin_type_var = tk.StringVar()
basin_dropdown = ttk.Combobox(selection_frame, textvariable=basin_type_var, width=30)
basin_dropdown.grid(row=1, column=1)

# Update basin type options dynamically
def update_basin_types(event=None):
    selected_setting = tectonic_setting_var.get()
    basin_types = df[df['Tectonic setting'] == selected_setting]['Basin type'].unique().tolist()
    basin_dropdown.set("")
    basin_dropdown['values'] = basin_types if basin_types else ["No Data Available"]

tectonic_dropdown.bind("<<ComboboxSelected>>", update_basin_types)

# Show detailed basin information in a scrollable window
def show_info():
    selected_setting = tectonic_setting_var.get()
    selected_basin = basin_type_var.get()
    filtered_df = df[(df['Tectonic setting'] == selected_setting) & (df['Basin type'] == selected_basin)]

    if filtered_df.empty:
        messagebox.showerror("Error", "Please select the basin type!")
        return

    selected_row = filtered_df.iloc[0]
    columns = ["Definition", "Key process", "Dominant rock and sediment type", "Basin shape ratio",
               "Heat flow(mW/m²)", "Crustal thickness(Km)", "Seismic depth(Km)", "Geochemical features",
               "Volcanic activity intensity", "Basin subsidence rate(m/Myr)", "Sediment compaction rate(%)",
               "Turbidite sediment production rate(cm/kyr)", "Mineral resources", "Modern Example",
               "Ancient example", "Example from Iran"]

    info_text = "\n".join([f"🔹 {col}: {selected_row.get(col, 'Not Available')}" for col in columns])

    # Display basin information in a scrollable text window
    info_window = tk.Toplevel(root)
    info_window.title("Basin Information")
    info_window.geometry("600x400")
    text_area = ScrolledText(info_window, wrap="word", font=("Arial", 10))
    text_area.insert("1.0", info_text)
    text_area.config(state="disabled")
    text_area.pack(expand=True, fill="both")

# Show symbolic basin figure with dynamic resizing
def show_image():
    selected_setting = tectonic_setting_var.get()
    selected_basin = basin_type_var.get()
    filtered_df = df[(df['Tectonic setting'] == selected_setting) & (df['Basin type'] == selected_basin)]

    if filtered_df.empty:
        messagebox.showerror("Error", "Please select the basin type!")
        return

    figure_name = filtered_df.iloc[0].get('Figure', None)
    if not figure_name:
        messagebox.showerror("Error", "Figure name is missing!")
        return

    image_path = os.path.join(fig_dir, f'{figure_name}.jpg')

    if os.path.exists(image_path):
        original_img = Image.open(image_path)
        original_width, original_height = original_img.size
        aspect_ratio = original_width / original_height

        # Function to resize image dynamically based on window size
        def resize_image(event=None):
            window_width = img_window.winfo_width()
            window_height = img_window.winfo_height()

            if window_width / window_height > aspect_ratio:
                new_height = window_height
                new_width = int(new_height * aspect_ratio)
            else:
                new_width = window_width
                new_height = int(new_width / aspect_ratio)

            resized_img = original_img.resize((new_width, new_height), Image.Resampling.LANCZOS)
            tk_image = ImageTk.PhotoImage(resized_img)
            img_label.config(image=tk_image)
            img_label.image = tk_image  # Keep reference

        # Create image window
        img_window = tk.Toplevel(root)
        img_window.title(f"Symbolic Figure of {selected_basin}")
        img_window.geometry("400x300")

        # Initial image display
        initial_img = original_img.resize((400, int(400 / aspect_ratio)), Image.Resampling.LANCZOS)
        img_tk = ImageTk.PhotoImage(initial_img)
        img_label = tk.Label(img_window, image=img_tk)
        img_label.image = img_tk
        img_label.pack(expand=True)

        # Bind window resize event to dynamically adjust image size
        img_window.bind("<Configure>", lambda e: root.after(50, resize_image))
    else:
        messagebox.showerror("Error", f"Image '{figure_name}.jpg' not found!")

# Show references from the Word document
def show_references():
    if not os.path.exists(reference_path):
        messagebox.showerror("Error", "Reference file not found!")
        return

    try:
        doc = docx.Document(reference_path)
        references = "\n".join([para.text for para in doc.paragraphs if para.text.strip()])

        ref_window = tk.Toplevel(root)
        ref_window.title("References")
        ref_window.geometry("600x400")
        text_area = ScrolledText(ref_window, wrap="word", font=("Arial", 10))
        text_area.insert("1.0", references)
        text_area.config(state="disabled")
        text_area.pack(expand=True, fill="both")

    except Exception as e:
        messagebox.showerror("Error", f"Failed to read reference file: {e}")

# Main action buttons
button_frame = tk.Frame(root)
button_frame.pack(pady=15)
tk.Button(button_frame, text="Show Basin Information", command=show_info, font=("Arial", 12), width=25).grid(row=0, column=0, padx=5)
tk.Button(button_frame, text="Show Symbolic Figure", command=show_image, font=("Arial", 12), width=25).grid(row=0, column=1, padx=5)
tk.Button(button_frame, text="Show References", command=show_references, font=("Arial", 12), width=25).grid(row=0, column=2, padx=5)

# Run GUI
root.mainloop()
