import sys
import os
import tkinter as tk
from tkinter import ttk
import RPi.GPIO as GPIO

# Add the parent directory to the module search path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from interface_board_pins import *  # Import pin assignments


# CONFIG
ADC_VALUES_UPDATE_INTERVAL_MS = 500
DIGITAL_INPUTS_UPDATE_INTERVAL_MS = 200
TAB_NOT_ACTIVE_CHECK_INTERVAL_MS = 2000
DEBUG = False


# Variables
updating_enabled = False


def create_control_tab(notebook, adc, shift_reg, pwm1, pwm2):
    frame = ttk.Frame(notebook)
    notebook.add(frame, text="Controls")

    digital_input_states = [tk.StringVar(value="LOW") for _ in range(8)]
    digital_output_states = [tk.BooleanVar(value=False) for _ in range(8)]
    adc_values = [tk.StringVar(value=" --- ") for _ in range(8)]
    pwm_values = [tk.IntVar(value=0), tk.IntVar(value=0)]
    output_buttons = {}  # Store button references to change colors


    def update_inputs():
        if not updating_enabled:
            frame.after(TAB_NOT_ACTIVE_CHECK_INTERVAL_MS, update_inputs)
            return
        for i, pin in enumerate(GPIO_DIGITAL_INPUTS.values()):
            digital_input_states[i].set("HIGH" if GPIO.input(pin) else "LOW")
        frame.after(DIGITAL_INPUTS_UPDATE_INTERVAL_MS, update_inputs)


    def update_adc():
        if not updating_enabled:
            frame.after(TAB_NOT_ACTIVE_CHECK_INTERVAL_MS, update_adc)
            return

        for terminal, config in ADC_TERMINALS.items():
            adc_channel = config["adc_channel"]
            max_value = config["max_value"]
            unit = config["unit"]

            # Read ADC value and scale to the correct voltage
            value = adc.read(adc_channel)
            adc_values[terminal].set(f"{value * max_value / 4095:4.2f} {unit}")

        frame.after(ADC_VALUES_UPDATE_INTERVAL_MS, update_adc)


    def toggle_output(index):
        """ Toggle shift register output and update button color. """
        new_state = not digital_output_states[index].get()
        digital_output_states[index].set(new_state)
        shift_reg.set_pin(index, new_state)

        if index in output_buttons:
            for btn in output_buttons[index]:
                btn.configure(bg="green" if new_state else "red", activebackground="green" if new_state else "red")


    style = ttk.Style()
    style.configure("TScale", thickness=60)
    style.configure("TButton", font=("Arial", 18), padding=5)

    control_frame = ttk.Frame(frame, padding=40)
    control_frame.grid(row=0, column=0, sticky="nsew")

    frame.grid_rowconfigure(0, weight=1)
    frame.grid_rowconfigure(1, weight=0)
    frame.grid_columnconfigure(0, weight=1)

    for i in range(8):
        ttk.Label(control_frame, text=f"ADC-{i}: ", font=("Arial", 18)).grid(row=i, column=0, sticky="e")
        ttk.Label(control_frame, textvariable=adc_values[i], width=10, font=("Arial", 18)).grid(row=i, column=1, sticky="w")
        ttk.Label(control_frame, text=f"IN-{i}:", font=("Arial", 18)).grid(row=i, column=2, sticky="e", padx=20)
        ttk.Label(control_frame, textvariable=digital_input_states[i], width=6, font=("Arial", 18)).grid(row=i, column=3, sticky="w")

        btn = tk.Button(control_frame, text=f"OUT-{i}", font=("Arial", 16), width=10, bg="red", activebackground="red", command=lambda i=i: toggle_output(i))
        btn.grid(row=i, column=4, sticky="w", padx=20)

        output_buttons.setdefault(i, []).append(btn)

        if i == 0:
            buzzer_btn = tk.Button(control_frame, text="BUZZER", font=("Arial", 16), width=10, bg="red", activebackground="red", command=lambda: toggle_output(0))
            buzzer_btn.grid(row=i, column=5, padx=20)
            output_buttons[0].append(buzzer_btn)

        if i == 1:
            relay2_btn = tk.Button(control_frame, text="RELAY2", font=("Arial", 16), width=10, bg="red", activebackground="red", command=lambda: toggle_output(1))
            relay2_btn.grid(row=i, column=5, padx=20)
            output_buttons[1].append(relay2_btn)

        if i == 2:
            relay1_btn = tk.Button(control_frame, text="RELAY1", font=("Arial", 16), width=10, bg="red", activebackground="red", command=lambda: toggle_output(2))
            relay1_btn.grid(row=i, column=5, padx=20)
            output_buttons[2].append(relay1_btn)

    pwm_frame = ttk.Frame(frame, padding=20)
    pwm_frame.grid(row=1, column=0, sticky="ew")

    pwm_frame.columnconfigure(0, weight=0)
    pwm_frame.columnconfigure(1, weight=1)
    pwm_frame.columnconfigure(2, weight=0)
    
    pwm1_label = ttk.Label(pwm_frame, text="PWM-1:", font=("Arial", 18))
    pwm1_label.grid(row=0, column=0, padx=20, sticky="e")
    
    pwm1_slider = ttk.Scale(
        pwm_frame, from_=0, to=100, orient="horizontal", length=400, 
        variable=pwm_values[0], command=lambda val: pwm1.ChangeDutyCycle(int(float(val)))
    )
    pwm1_slider.grid(row=0, column=1, columnspan=2, sticky="we", padx=10)
    
    pwm2_label = ttk.Label(pwm_frame, text="PWM-2:", font=("Arial", 18))
    pwm2_label.grid(row=1, column=0, padx=20, sticky="e")
    
    pwm2_slider = ttk.Scale(
        pwm_frame, from_=0, to=100, orient="horizontal", length=400, 
        variable=pwm_values[1], command=lambda val: pwm2.ChangeDutyCycle(int(float(val)))
    )
    pwm2_slider.grid(row=1, column=1, columnspan=2, sticky="we", padx=10)

    update_inputs()
    update_adc()



def set_updating_enabled(is_active):
    global updating_enabled
    updating_enabled = is_active
    if DEBUG: print(f"control tab: set updating_enabled to {updating_enabled}")