import customtkinter as ctk
import os
import threading
import datetime
from pystray import Icon as TrayIcon, Menu, MenuItem
from PIL import Image, ImageDraw
import sys
import subprocess
import webbrowser
import psutil

LOG_REFRESH_SECONDS = 10
MAIN_DIR = os.getcwd()
LOG_DIR = os.path.join(MAIN_DIR, 'Logs')
EXPORTER_LOG = os.path.join(LOG_DIR, f"MSSQL_exporter_log_{datetime.datetime.now().strftime('%Y-%m-%d')}.txt")
IMPORTER_LOG = os.path.join(LOG_DIR, f"SDF_importer_log_{datetime.datetime.now().strftime('%Y-%m-%d')}.txt")
MAIN_EXE = os.path.join(MAIN_DIR, 'main.exe')
ENV_FILE = os.path.join(MAIN_DIR, '.env')


def resource_path(relative_path):
    """Korrekt aufgelöst für PyInstaller und normale Ausführung"""
    try:
        base_path = sys._MEIPASS
    except AttributeError:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, relative_path)


class LogMonitorApp(ctk.CTk):

    def __init__(self):
        super().__init__()
        self.title('SDF-Dienstüberwachung')
        self.geometry('500x350')
        ctk.set_appearance_mode('dark')
        ctk.set_default_color_theme('blue')

        self.title_label = ctk.CTkLabel(self, text='SDF Monitor', font=ctk.CTkFont(size=24, weight='bold'))
        self.title_label.pack(pady=(10, 0))

        self.status_label = ctk.CTkLabel(self, text='Letzte Ausführungen laden...')
        self.status_label.pack(pady=(20, 0))

        self.seconds_remaining = LOG_REFRESH_SECONDS
        self.countdown_label = ctk.CTkLabel(self, text=f'Nächster Check in: {self.seconds_remaining}s')
        self.countdown_label.pack(pady=5)

        self.update_logs()
        self.update_countdown()

        self.folder_button = ctk.CTkButton(self, text='Logs-Ordner öffnen', command=self.open_log_folder)
        self.folder_button.pack(pady=10)

        self.env_button = ctk.CTkButton(self, text='.env Datei öffnen', command=self.open_env_file)
        self.env_button.pack(pady=5)

        self.restart_button = ctk.CTkButton(self, text='Services neu starten', command=self.restart_main_exe)
        self.restart_button.pack(pady=10)

        self.stop_button = ctk.CTkButton(self, text='Services beenden', command=self.stop_main_exe)
        self.stop_button.pack(pady=5)

        logo_path = resource_path('logo.png')
        if os.path.exists(logo_path):
            from PIL import Image as PILImage
            logo_img = PILImage.open(logo_path).resize((120, 40))
            self.logo_image = ctk.CTkImage(light_image=logo_img, dark_image=logo_img, size=(120, 40))
            self.logo_label = ctk.CTkLabel(self, image=self.logo_image, text='', cursor='hand2')
        else:
            self.logo_label = ctk.CTkLabel(self, text='www.deine-website.de', text_color='skyblue', cursor='hand2')
        self.logo_label.pack(pady=5)
        self.logo_label.bind('<Button-1>', lambda e: webbrowser.open('https://www.deine-website.de'))

        self.protocol('WM_DELETE_WINDOW', self.hide_to_tray)
        self.bind('<Unmap>', self.on_minimize)

        self.create_tray_icon()

    def format_time(self, path):
        if os.path.exists(path):
            t = datetime.datetime.fromtimestamp(os.path.getmtime(path))
            return t.strftime('%Y-%m-%d %H:%M:%S')
        return 'Nie'

    def update_logs(self):
        exporter_time = self.format_time(EXPORTER_LOG)
        importer_time = self.format_time(IMPORTER_LOG)
        self.status_label.configure(text=f'Letzter Export: {exporter_time}\nLetzter Import: {importer_time}')

    def update_countdown(self):
        self.countdown_label.configure(text=f'Nächster Check in: {self.seconds_remaining}s')
        self.seconds_remaining -= 1
        if self.seconds_remaining <= 0:
            self.update_logs()
            self.seconds_remaining = LOG_REFRESH_SECONDS
        self.after(1000, self.update_countdown)

    def restart_main_exe(self):
        try:
            if os.path.exists(MAIN_EXE):
                subprocess.Popen([MAIN_EXE])
                self.write_status('main.exe wurde neu gestartet.')
            else:
                self.write_status('main.exe nicht gefunden.')
        except Exception as e:
            self.write_status(f'Fehler beim Starten von main.exe: {e}')

    def write_status(self, msg):
        now = datetime.datetime.now().strftime('%H:%M:%S')
        self.status_label.configure(text=f'[{now}] {msg}')

    def open_log_folder(self):
        os.startfile(LOG_DIR)

    def open_env_file(self):
        if os.path.exists(ENV_FILE):
            os.startfile(ENV_FILE)
        else:
            self.write_status('.env Datei nicht gefunden.')

    def hide_to_tray(self):
        self.withdraw()
        self.tray_icon.visible = True

    def show_from_tray(self, icon=None, item=None):
        self.deiconify()
        self.tray_icon.visible = False

    def quit_app(self, icon, item):
        self.tray_icon.stop()
        self.destroy()
        sys.exit()

    def on_minimize(self, event):
        if self.state() == 'iconic':
            self.hide_to_tray()

    def create_tray_icon(self):
        icon_path = resource_path('icon.ico')
        if os.path.exists(icon_path):
            image = Image.open(icon_path).resize((64, 64))
        else:
            image = Image.new('RGB', (64, 64), 'black')
            draw = ImageDraw.Draw(image)
            draw.rectangle((16, 16, 48, 48), fill='white')
        menu = Menu(MenuItem('Öffnen', self.show_from_tray), MenuItem('Beenden', self.quit_app))
        self.tray_icon = TrayIcon('SDF-Monitor', image, 'SDF-Monitor', menu)
        threading.Thread(target=self.tray_icon.run, daemon=True).start()

    def stop_main_exe(self):
        found = False
        for proc in psutil.process_iter(['pid', 'name']):
            try:
                if proc.info['name'].lower() == 'main.exe':
                    proc.kill()
                    found = True
                    self.write_status('main.exe wurde beendet.')
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                pass

        if not found:
            self.write_status('main.exe läuft nicht.')


if __name__ == '__main__':
    app = LogMonitorApp()
    app.mainloop()
