import sys
import os
import ctypes
import time
import sqlite3
import psutil
import win32gui
from PyQt5.QtWidgets import  QSystemTrayIcon, QMenu, QAction,QStyledItemDelegate,QTextEdit,QSplitter, QLineEdit, QFrame, QApplication, QSizePolicy, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QComboBox, QMessageBox, QAction, QDialog
from PyQt5.QtCore import Qt, QDateTime, QThread, pyqtSignal,QTimer
from PyQt5.QtGui import QPixmap, QFont, QIcon
from pynput import mouse, keyboard
from qt_material import apply_stylesheet
from PIL import ImageGrab
from MainReportLocal import MainReportLocal
import requests
import socket
import urllib3
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from  MessageInfo import  MessageInfo
from  ProjectInfo import  ProjectInfo
from  TaskInfo import  TaskInfo
from  MainReportSend import  MainReportSend
import json
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from win32com.client import Dispatch
import pythoncom
import asyncio
import websockets
import ssl
import websockets
from PyQt5.QtGui import QPixmap, QIcon
from  langHandel import langHandel
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

class ScreenshotRemoteSocketThread(QThread):
    def __init__(self, shift_widget=None):
        super().__init__()
        self.shift_widget = shift_widget

        # تعریف نمونه `ReportThread`
        self.report_thread = ReportThread(self.shift_widget)
        self.report_thread.finished.connect(self.on_report_finished)

    def run(self):
        self.take_screenshot()

    def stop(self):
        self.running = False

    def get_active_window_info(self):
        try:
            # مقداردهی اولیه کتابخانه COM
            pythoncom.CoInitialize()

            # دریافت اطلاعات پنجره فعال
            hwnd = ctypes.windll.user32.GetForegroundWindow()
            pid = ctypes.c_ulong()
            ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
            process = psutil.Process(pid.value)
            window_title = win32gui.GetWindowText(hwnd)
            exe_path = process.exe()

            if exe_path is None:
                return "برنامه فعالی یافت نشد"

            exe_name = os.path.basename(exe_path)

            # دریافت مسیر میانبرهای منوی استارت
            start_menu_paths = [
                os.path.join(os.getenv('APPDATA'), r'Microsoft\Windows\Start Menu\Programs'),
                os.path.join(os.getenv('PROGRAMDATA'), r'Microsoft\Windows\Start Menu\Programs')
            ]

            shortcuts = {}
            for path in start_menu_paths:
                for root, _, files in os.walk(path):
                    for file in files:
                        if file.endswith('.lnk'):
                            shortcut_path = os.path.join(root, file)
                            shell = Dispatch('WScript.Shell')
                            shortcut = shell.CreateShortcut(shortcut_path)
                            target_path = shortcut.Targetpath
                            if target_path:
                                exe_name_shortcut = os.path.basename(target_path)
                                display_name = file.replace('.lnk', '')
                                shortcuts[exe_name_shortcut] = display_name

            display_name = shortcuts.get(exe_name, exe_name)
            return display_name, window_title
        except Exception as e:
            print(f"Error: {e}")
            return None, None

    def take_screenshot(self):
        projectId = 0
        taskId = 0
        try:
            # گرفتن نام برنامه و عنوان تب فعال
            appname, tabtitle = self.get_active_window_info()
        except:
            print("error Get name App")
        try:
            selected_task_index = self.shift_widget.project_combo.currentIndex()
            projectId = self.shift_widget.project_combo.itemData(selected_task_index, Qt.UserRole)
            selected_task_index = self.shift_widget.task_combo.currentIndex()
            taskId = self.shift_widget.task_combo.itemData(selected_task_index, Qt.UserRole)

        except:
            print("error get Id")
        try:
            screenshot = ImageGrab.grab()
            timestamp = int(time.time())
            if not os.path.exists('screenshots'):
                os.makedirs('screenshots')
            screenshot_file = f'screenshots/screenshot_{timestamp}.png'
            screenshot.save(screenshot_file)



            # ذخیره اطلاعات اسکرین‌شات در دیتابیس
            conn = sqlite3.connect('reports.db')
            cursor = conn.cursor()
            cursor.execute('''
                 INSERT INTO reports (timestamp, screenshot_file, active_project, active_task, mouse_clicks, keyboard_clicks, appname, tabtitle,projectId,taskId)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?,?,?)
            ''', (
                QDateTime.currentDateTime().toString(Qt.DefaultLocaleLongDate),
                screenshot_file,
                self.shift_widget.project_combo.currentText(),
                self.shift_widget.task_combo.currentText(),
                self.shift_widget.shift_thread.mouse_clicks,
                self.shift_widget.shift_thread.keyboard_clicks,
                appname,
                tabtitle,
                str(projectId),
                str(taskId),
            ))
            conn.commit()
            conn.close()
            # شروع `ReportThread` برای ارسال گزارش‌ها به سرور
            self.report_thread.start()
        except Exception as e:
            print(f"Error taking screenshot: {e}")

    def on_report_finished(self, result):
        if result:
            print("گزارش‌ها با موفقیت ارسال شدند.")
        else:
            print("خطا در ارسال گزارش‌ها.")

class WebSocketClientThread(QThread):
    def __init__(self, user_id, parent=None,shift_widget=None ):
        super(WebSocketClientThread, self).__init__(parent)
        with open("data.json", "r", encoding='utf-8') as file:
            data = json.load(file)
        self.language = langHandel("panel")
        host =   data.get("host")
        self.shift_widget = shift_widget
        self.user_id = user_id
        self.screenSocket=ScreenshotRemoteSocketThread(shift_widget=self.shift_widget)
        self.websocket_url = f'wss://{host}/ws?userId={self.user_id}'
        self.ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

        # ایجاد ssl_context با غیرفعال کردن اعتبارسنجی گواهینامه
        self.ssl_context = ssl.create_default_context()
        self.ssl_context.check_hostname = False
        self.ssl_context.verify_mode = ssl.CERT_NONE

    async def connect_to_websocket(self):
        while True:
            try:
                async with websockets.connect(self.websocket_url, ssl=self.ssl_context) as websocket:
                    await websocket.send(self.user_id)
                    #print(f"Sent user_id: {self.user_id}")

                    while True:
                        try:
                            message = await websocket.recv()
                            #print(f"Received message: {message}")
                            data = json.loads( message )

                            # بررسی نوع پیام
                            message_type = data.get("type")
                            content = data.get("content")
                            extra_data = data.get("data")

                            if message_type == "notification":
                                self.show_Succ(self.language.get_value( "managementMessage"), content)
                                #print(f"Notification: {content}")
                                # نمایش نوتیفیکیشن یا انجام عملیات مرتبط با اعلان

                            elif message_type == "join":
                                print(f"Welcome Message: {content}")
                                # نمایش پیام خوش آمدگویی

                            elif message_type == "screenshot":
                                self.screenSocket.start()
                                self.screenSocket.stop()
                                #print(f"Screenshot Data: {extra_data}")
                                # پردازش داده‌های اسکرین‌شات
                            else:
                                print(f"Unknown type: {message_type}")

                        except websockets.exceptions.ConnectionClosed:
                            print("Connection closed")
                            break
            except Exception as e:
                print(f"Error: {e}")

            print("Reconnecting in 20 seconds...")
            time.sleep(20)

    def run(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(self.connect_to_websocket())
        loop.close()

    def show_Succ(self, title, message):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setWindowTitle(title)
        msg.setText(message)
        msg.exec_()
# ایجاد دیتابیس و جدول گزارشات
def init_db():
    conn = sqlite3.connect('reports.db')
    cursor = conn.cursor()
    cursor.execute('''
           CREATE TABLE IF NOT EXISTS reports (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            screenshot_file TEXT,
            active_project TEXT,
            active_task TEXT,
            mouse_clicks INTEGER,
            keyboard_clicks INTEGER,
            appname TEXT,
            tabtitle TEXT,
            projectId TEXT,
            taskId TEXT
        )
    ''')
    conn.commit()
    conn.close()


class ShiftThread(QThread):
    count_updated = pyqtSignal(int, int)

    def __init__(self):
        super().__init__()
        self.mouse_clicks = 0
        self.keyboard_clicks = 0
        self.running = False

    def on_click(self, x, y, button, pressed):
        if self.running and pressed:
            self.mouse_clicks += 1
            self.count_updated.emit(self.mouse_clicks, self.keyboard_clicks)

    def on_press(self, key):
        if self.running:
            self.keyboard_clicks += 1
            self.count_updated.emit(self.mouse_clicks, self.keyboard_clicks)

    def run(self):
        self.running = True
        try:
            with mouse.Listener(on_click=self.on_click) as self.mouse_listener, keyboard.Listener(
                    on_press=self.on_press) as self.keyboard_listener:
                while self.running:
                    time.sleep(0.1)
        finally:
            self.mouse_listener.stop()
            self.keyboard_listener.stop()

    def stop(self):
        self.running = False


class ScreenshotThread(QThread):
    def __init__(self, interval=10, shift_widget=None):
        super().__init__()
        self.interval = interval
        self.running = False
        self.shift_widget = shift_widget
        self.dataLogin=[]
        if os.path.exists("login.json") and os.path.getsize("login.json") > 0:
            with open("login.json", "r", encoding='utf-8') as file:
                self.dataLogin = json.load(file)

        # تعریف نمونه `ReportThread`
        self.report_thread = ReportThread(self.shift_widget)
        self.report_thread.finished.connect(self.on_report_finished)

    def run(self):
        self.running = True
        while self.running:
            self.take_screenshot()
            time.sleep(self.interval)

    def stop(self):
        self.running = False

    def get_active_window_info(self):
        try:
            # مقداردهی اولیه کتابخانه COM
            pythoncom.CoInitialize()

            # دریافت اطلاعات پنجره فعال
            hwnd = ctypes.windll.user32.GetForegroundWindow()
            pid = ctypes.c_ulong()
            ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
            process = psutil.Process(pid.value)
            window_title = win32gui.GetWindowText(hwnd)
            exe_path = process.exe()

            if exe_path is None:
                return "برنامه فعالی یافت نشد"

            exe_name = os.path.basename(exe_path)

            # دریافت مسیر میانبرهای منوی استارت
            start_menu_paths = [
                os.path.join(os.getenv('APPDATA'), r'Microsoft\Windows\Start Menu\Programs'),
                os.path.join(os.getenv('PROGRAMDATA'), r'Microsoft\Windows\Start Menu\Programs')
            ]

            shortcuts = {}
            for path in start_menu_paths:
                for root, _, files in os.walk(path):
                    for file in files:
                        if file.endswith('.lnk'):
                            shortcut_path = os.path.join(root, file)
                            shell = Dispatch('WScript.Shell')
                            shortcut = shell.CreateShortcut(shortcut_path)
                            target_path = shortcut.Targetpath
                            if target_path:
                                exe_name_shortcut = os.path.basename(target_path)
                                display_name = file.replace('.lnk', '')
                                shortcuts[exe_name_shortcut] = display_name

            display_name = shortcuts.get(exe_name, exe_name)
            return display_name, window_title
        except Exception as e:
            print(f"Error: {e}")
            return None, None

    def take_screenshot(self):
        projectId = 0
        taskId = 0
        try:
            # گرفتن نام برنامه و عنوان تب فعال
            appname, tabtitle = self.get_active_window_info()
        except:
            print("error Get name App")
        try:
            selected_task_index = self.shift_widget.project_combo.currentIndex()
            projectId = self.shift_widget.project_combo.itemData(selected_task_index, Qt.UserRole)
            selected_task_index = self.shift_widget.task_combo.currentIndex()
            taskId = self.shift_widget.task_combo.itemData(selected_task_index, Qt.UserRole)

        except:
            print("error get Id")
        try:
            mouse_click="0"
            keyboard_click="0"
            if(self.dataLogin.get("accessClinetScreenShot")=="access"):
                screenshot = ImageGrab.grab()
                timestamp = int(time.time())
                if not os.path.exists('screenshots'):
                    os.makedirs('screenshots')
                screenshot_file = f'screenshots/screenshot_{timestamp}.png'
                screenshot.save(screenshot_file)
            else:
                screenshot_file=""

            if (self.dataLogin.get("accessClinetScreenShot") == "access"):
                 mouse_click=self.shift_widget.shift_thread.mouse_clicks
                 keyboard_click=self.shift_widget.shift_thread.keyboard_clicks
            if (self.dataLogin.get("accessClinetOpenApp") != "access"):
                 appname=""
            if (self.dataLogin.get("accessClinetOpenTab") != "access"):
                 tabtitle=""

            # ذخیره اطلاعات اسکرین‌شات در دیتابیس
            conn = sqlite3.connect('reports.db')
            cursor = conn.cursor()
            cursor.execute('''
                 INSERT INTO reports (timestamp, screenshot_file, active_project, active_task, mouse_clicks, keyboard_clicks, appname, tabtitle,projectId,taskId)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?,?,?)
            ''', (
                QDateTime.currentDateTime().toString(Qt.DefaultLocaleLongDate),
                screenshot_file,
                self.shift_widget.project_combo.currentText(),
                self.shift_widget.task_combo.currentText(),
                mouse_click,
                keyboard_click,
                appname,
                tabtitle,
                str(projectId),
                str(taskId),
            ))
            conn.commit()
            conn.close()
            # شروع `ReportThread` برای ارسال گزارش‌ها به سرور
            self.report_thread.start()
        except Exception as e:
            print(f"Error taking screenshot: {e}")

    def on_report_finished(self, result):
        if result:
            print("گزارش‌ها با موفقیت ارسال شدند.")
        else:
            print("خطا در ارسال گزارش‌ها.")


class ReportThread(QThread):
    finished = pyqtSignal(bool)  # سیگنال برای اتمام عملیات

    def __init__(self, shift_widget):
        super().__init__()
        self.shift = shift_widget

    def run(self):
        result = self.send_reports_to_server()
        self.finished.emit(result)

    def send_reports_to_server(self):
        try:
            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

            # اتصال به دیتابیس
            conn = sqlite3.connect('reports.db')
            cursor = conn.cursor()

            # انتخاب همه رکوردها از جدول reports
            cursor.execute("SELECT * FROM reports")
            records = cursor.fetchall()

            # باز کردن فایل تصویر به صورت باینری
            info_connection = get_client_info()
            with open("data.json", "r", encoding='utf-8') as file:
                data = json.load(file)

            # دریافت فیلد host
            host = "https://" + data.get("host")

            with open("login.json", "r", encoding='utf-8') as file:
                login = json.load(file)

            # دریافت فیلد token
            token = login.get("token")
            url = f"{host}/frogment/apis/ReportForShift"
            for record in records:
                record_id, timestamp, screenshot_file, active_project, active_task, mouse_clicks, keyboard_clicks, appname, tabtitle,projectId,taskId = record
                dataActive = {
                    'timestamp': timestamp,
                    'active_project': active_project,
                    'active_task': active_task,
                    'mouse_clicks': mouse_clicks,
                    'keyboard_clicks': keyboard_clicks,
                    'appname': appname,
                    'tabtitle': tabtitle,
                    'ShiftId': self.shift.shiftId,
                    'token': token,
                    'Ip': info_connection["ip_address"],
                    'NameClinets': info_connection["hostname"],
                    'projectId':projectId,
                    'taskId':taskId,
                }

                try:
                    headers = {
                        "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
                    }
                    files = None

                    if screenshot_file and screenshot_file.strip():
                        with open(screenshot_file, 'rb') as file:
                            files = {'CoverFile': file}
                            response = requests.request("POST", url,headers=headers, data=dataActive, files=files, verify=False)
                    else:
                        response = requests.request("POST", url, headers=headers, data=dataActive,
                                                    verify=False)

                    if response.status_code == 200:
                        print(f"داده‌ها با موفقیت ارسال شدند: {record_id}")
                        # حذف رکورد از دیتابیس
                        cursor.execute("DELETE FROM reports WHERE id = ?", (record_id,))
                        conn.commit()
                        if screenshot_file and screenshot_file.strip():
                            os.remove(screenshot_file)
                    else:
                        print(response.status_code)
                        print(f"خطا در ارسال داده‌ها: {record_id}")
                        continue  # ادامه پردازش در صورت بروز خطا
                except requests.RequestException as e:
                    print(f"خطا در ارسال داده‌ها: {e}")
                    continue  # ادامه پردازش در صورت بروز خطا
                except Exception as e:
                    print(f"خطا در باز کردن فایل یا حذف آن: {e}")
                    continue  # ادامه پردازش در صورت بروز خطا

            # بستن اتصال به دیتابیس
            conn.close()
            return True
        except Exception as e:
            print(f"Error in send_reports_to_server: {e}")
            return False


class ShiftWorker(QThread):
    shift_started = pyqtSignal(bool)
    shift_ended = pyqtSignal(bool)
    update_status = pyqtSignal(str)
    ShiftId = pyqtSignal(int)
    timeStarted = pyqtSignal(str)

    def __init__(self, action,closed=False,event=None, parent=None):
        super().__init__(parent)
        self.language = langHandel("panel")
        self.action = action  # 'start' or 'end'
        self.info_connection = get_client_info()
        self.closed = closed
        self.event=event



    def run(self):
        self.update_status.emit(self.language.get_value( "Connecting"))

        with open("data.json", "r", encoding='utf-8') as file:
            data = json.load(file)

        host = "https://" + data.get("host")
        with open("login.json", "r", encoding='utf-8') as file:
            login = json.load(file)

        token = login.get("token")
        if self.action == 'start':
            self.start_shift(host, token)
        elif self.action == 'end':
            self.end_shift(host, token)

    def start_shift(self, host, token):
        url = f"{host}/frogment/apis/StartShift"
        payload = {'Token': token, "ip": self.info_connection["ip_address"],
                   "NameClinets": self.info_connection["hostname"]}

        try:
            headers = {
                "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
                "Content-Type": "application/x-www-form-urlencoded"
            }
            response = requests.request("POST", url,headers=headers, data=payload, verify=False)
            response.raise_for_status()
            response_json = response.json()
            if response_json["status"] == "200":
                with open("shift.json", "w", encoding='utf-8') as file:
                    json.dump(response_json, file, ensure_ascii=False, indent=4)
                self.ShiftId.emit(int(response_json["data"] ))
                self.shift_started.emit(True)
                self.update_status.emit(self.language.get_value( "startedshift"))
                self.timeStarted.emit(response_json["started"])
                if self.closed:
                    self.event.tray_icon.hide()
                    QApplication.instance().quit()
            else:
                self.shift_started.emit(False)
                self.update_status.emit(self.language.get_value( "errorstartedshifts"))
        except requests.exceptions.HTTPError:
            self.shift_started.emit(False)
            self.update_status.emit(self.language.get_value( "errorstartedshiftcheck"))
        except Exception:
            self.shift_started.emit(False)
            self.update_status.emit(self.language.get_value( "errorstartedshiftEx"))

    def end_shift(self, host, token):
        endSend=False
        #start send_to_server
        headers = {
            "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
            "Content-Type": "application/x-www-form-urlencoded"
        }
        try:

            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
            self.update_status.emit(self.language.get_value( "sendingReport"))
            # اتصال به دیتابیس
            conn = sqlite3.connect('reports.db')
            cursor = conn.cursor()

            # انتخاب همه رکوردها از جدول reports
            cursor.execute("SELECT * FROM reports")
            records = cursor.fetchall()

            # باز کردن فایل تصویر به صورت باینری
            info_connection = get_client_info()
            with open("data.json", "r", encoding='utf-8') as file:
                data = json.load(file)

            # دریافت فیلد host
            host = "https://" + data.get("host")

            with open("login.json", "r", encoding='utf-8') as file:
                login = json.load(file)

            # دریافت فیلد token
            token = login.get("token")
            url = f"{host}/frogment/apis/ReportForShift"

            for record in records:
                record_id, timestamp, screenshot_file, active_project, active_task, mouse_clicks, keyboard_clicks, appname, tabtitle,projectId,taskId = record
                dataActive = {
                    'timestamp': timestamp,
                    'active_project': active_project,
                    'active_task': active_task,
                    'mouse_clicks': mouse_clicks,
                    'keyboard_clicks': keyboard_clicks,
                    'appname': appname,
                    'tabtitle': tabtitle,
                    'ShiftId': self.ShiftId,
                    'token': token,
                    'Ip': info_connection["ip_address"],
                    'NameClinets': info_connection["hostname"],
                    'projectId':projectId,
                    'taskId':taskId,
                }

                try:
                    files = None

                    if screenshot_file and screenshot_file.strip():
                        with open(screenshot_file, 'rb') as file:
                            files = {'CoverFile': file}
                            response = requests.request("POST", url, headers=headers, data=dataActive, files=files,
                                                        verify=False)
                    else:
                        response = requests.request("POST", url, headers=headers, data=dataActive,
                                                    verify=False)
                    if response.status_code == 200:
                        print(f"داده‌ها با موفقیت ارسال شدند: {record_id}")
                        # حذف رکورد از دیتابیس
                        cursor.execute("DELETE FROM reports WHERE id = ?", (record_id,))
                        conn.commit()
                        if screenshot_file and screenshot_file.strip():
                            os.remove(screenshot_file)


                    else:
                        print(f"خطا در ارسال داده‌ها: {record_id}")
                        continue  # ادامه پردازش در صورت بروز خطا
                except requests.RequestException as e:
                    print(f"خطا در ارسال داده‌ها: {e}")
                    continue  # ادامه پردازش در صورت بروز خطا
                except Exception as e:
                    print(f"خطا در باز کردن فایل یا حذف آن: {e}")
                    continue  # ادامه پردازش در صورت بروز خطا

            # بستن اتصال به دیتابیس
            conn.close()
            endSend=True
        except Exception as e:
            print(f"Error in send_reports_to_server: {e}")
            endSend = False

        #end send_reports_to_server
        if endSend:
            self.update_status.emit(self.language.get_value( "shiftend"))
            url = f"{host}/frogment/apis/EndShift"
            payload = {'Token': token, "ip": self.info_connection["ip_address"],
                       "NameClinets": self.info_connection["hostname"]}

            try:

                response = requests.request("POST", url,headers=headers, data=payload, verify=False)
                response.raise_for_status()
                response_json = response.json()
                if response_json["status"] == "200":
                    with open("shift.json", "w", encoding='utf-8') as file:
                        file.write('{"data": 0, "started":""}')
                    self.shift_ended.emit(True)
                    self.update_status.emit(self.language.get_value( "successfullyshiftend"))
                    self.ShiftId.emit(0)
                    self.timeStarted.emit(self.language.get_value( "started"))
                else:
                    self.shift_ended.emit(False)
                    self.shift_started.emit(True)
                    self.update_status.emit("خطایی در ثبت پایان رخ داد دوبار سعی کنید")
            except requests.exceptions.HTTPError:
                self.shift_ended.emit(False)
                self.shift_started.emit(True)
                self.update_status.emit(self.language.get_value( "errorshiftend"))
            except Exception:
                self.shift_ended.emit(False)
                self.shift_started.emit(True)
                self.update_status.emit(self.language.get_value( "errorshiftendEx"))
        else:
            self.shift_ended.emit(False)
            self.shift_started.emit(True)
            self.update_status.emit(self.language.get_value( "errorshiftendEx"))


class MainDashboard(QMainWindow):
    def __init__(self):
        super().__init__()
        init_db()
        # Set window properties
        user32 = ctypes.windll.user32
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        left = screen_width - 730
        top = screen_height - 420
        self.language = langHandel("panel")
        self.setWindowTitle("EM Dashboard")
        self.setGeometry(left, top, 700, 300)
        self.setWindowIcon(QIcon('ixo.png'))



        # Central widget and layout
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        # Adding Splitter to divide profile and other items
        splitter = QSplitter(Qt.Horizontal)
        self.layout.addWidget(splitter)

        # Profile Widget
        self.profile_widget = ProfileWidget()

        # Other Items Widget
        other_items_widget = QWidget()
        other_items_layout = QVBoxLayout()
        other_items_widget.setLayout(other_items_layout)
        splitter.addWidget(other_items_widget)

        # Adding ShiftWidget to other items widget
        self.shift_widget = ShiftWidget(self)
        splitter.addWidget(self.shift_widget)
        other_items_layout.addWidget(self.profile_widget)


        # Adding menu bar
        self.initMenuBar()

        # Set up the system tray icon
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon('ixo.ico'))  # Replace 'icon.png' with your icon file

        # Add menu to system tray
        tray_menu = QMenu(self)
        restore_action = QAction(self.language.get_value( "open"), self)
        restore_action.triggered.connect(self.show_window)
        tray_menu.addAction(restore_action)

        quit_action = QAction(self.language.get_value( "close"), self)
        quit_action.triggered.connect(self.quit_application)
        tray_menu.addAction(quit_action)

        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()

        # Connect double click on tray icon to show the application
        self.tray_icon.activated.connect(self.on_tray_icon_activated)

    def closeEvent(self, event):
        event.ignore()
        self.hide()
        self.tray_icon.showMessage(
            "System Tray",
            "Application minimized to tray. Click the tray icon to restore.",
            QSystemTrayIcon.Information,
            2000
        )

    def on_tray_icon_activated(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            self.show_window()

    def show_window(self):
        self.show()
        self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive)
        self.activateWindow()

    def quit_application(self):
        try:
            if os.path.exists("shift.json") and os.path.getsize("shift.json") > 0:
                with open("shift.json", "r", encoding='utf-8') as file:
                    content = file.read().strip()
                    if content:
                        shift = json.loads(content)
                        if shift.get("data") != 0:
                            exist = True
                        else:
                            exist = False

            else:
                shift = {}
                exist = False
        except:
            print("Error Read")
            exist = False

        if exist:
            reply = QMessageBox.question(self, 'تایید پایان شیفت',
                                         'اگر می خواهید برنامه را ببندید و شیفت خود را به پایان برسانید ، Yes را انتخاب کنید',
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.endShift = ShiftWorker("end", True, self)
                self.endShift.run()

            else:
                self.show_window()
        else:
            reply = QMessageBox.question(self, 'تایید خروج', 'از از بستن برنامه اطمینان دارید؟',
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.tray_icon.hide()
                QApplication.instance().quit()
            else:
                self.show_window()




    def initMenuBar(self):
        # Menu bar creation
        menubar = self.menuBar()
        # تنظیم جهت‌گیری منوها به راست‌به‌چپ
        # menubar.setLayoutDirection(Qt.RightToLeft)

        # Adding main menus
        account = menubar.addMenu(self.language.get_value( "useraccount"))
        activities = menubar.addMenu(self.language.get_value( "activities"))
        reports = menubar.addMenu(self.language.get_value( "Reports"))
        helpMenu = menubar.addMenu(self.language.get_value( "guide"))

        # Adding actions to Account menu
        refreshAction = QAction(self.language.get_value( "refresh"), self)
        refreshAction.triggered.connect(self.refresh)
        viewProfileAction = QAction(self.language.get_value( "account"), self)
        viewProfileAction.triggered.connect(self.showProfile)

        MyMessageUser = QAction(self.language.get_value( "mymessages"), self)
        MyMessageUser.triggered.connect(self.myMessage)

        thems = QAction(self.language.get_value( "changeThem"), self)
        thems.triggered.connect(self.change_thems)

        Language = QAction("Language", self)
        Language.triggered.connect(self.change_Language)

        logoutAction = QAction(self.language.get_value( "Exit"), self)
        logoutAction.triggered.connect(self.logout)

        account.addAction(refreshAction)
        account.addAction(viewProfileAction)
        account.addAction(MyMessageUser)
        account.addAction(thems)
        account.addAction(Language)
        account.addSeparator()
        account.addAction(logoutAction)

        # Adding actions to Activities menu
        projectsAction = QAction(self.language.get_value( "projects"), self)
        projectsAction.triggered.connect(self.showProject)
        tasksAction = QAction(self.language.get_value( "tasks"), self)
        tasksAction.triggered.connect(self.showTasks)


        activities.addAction(projectsAction)
        activities.addAction(tasksAction)

        # Adding actions to Reports menu
        projectReportAction = QAction(self.language.get_value( "sendReports"), self)
        projectReportAction.triggered.connect(self.gotoReportMy)
        generalReportAction = QAction(self.language.get_value( "recordedReports"), self)
        generalReportAction.triggered.connect(self.gotoLocalReport)


        reports.addAction(projectReportAction)
        reports.addAction(generalReportAction)

        # Adding action to Help menu
        helpAction = QAction(self.language.get_value( "ViewGuide"), self)
        helpAction.triggered.connect(self.show_help)

        helpMenu.addAction(helpAction)
    def myMessage(self):
        window=MessageInfo()
        window.show()
    def change_thems(self):
        dialog = ThemeSelectorDialog()
        if dialog.exec_():
            self.tray_icon.hide()
            QApplication.instance().quit()
    def change_Language(self):
        dialog = LanguageSelectorDialog()
        if dialog.exec_():
            self.tray_icon.hide()
            QApplication.instance().quit()
    def showProfile(self):
        dialog = DetailDialogProfile()
        dialog.exec_()
    def showProject(self):
        window=ProjectInfo()
        window.show()
    def showTasks(self):
        window=TaskInfo()
        window.show()
    def refresh(self):
        self.shift_widget.update_status(self.language.get_value( "Updating") )
        self.shift_widget.setProject()
        self.shift_widget.setTask()
        self.shift_widget.update_status(self.language.get_value( "updated"))

    def show_error(self, title, message):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setWindowTitle(title)
        msg.setText(message)
        msg.exec_()
    def logout(self):
        try:
            if os.path.exists("shift.json") and os.path.getsize("shift.json") > 0:
                with open("shift.json", "r", encoding='utf-8') as file:
                    shift = json.load(file)
                    print(shift)
                    if shift.get("data") != 0:
                        print(shift)
                        exist = True
                    else:
                        exist = False

            else:
                shift = {}
                exist = False
        except:
            print("Error Read")
            exist = False

        if exist:
            self.show_error(self.language.get_value( "error"),self.language.get_value( "errorEndShiftLogout"))
        else:
            self.show_error(self.language.get_value( "successfulexit"), self.language.get_value( "successfullysigned"))
            try:
                with open("shift.json", "w", encoding='utf-8') as file:
                    file.write('{"data": 0, "started":""}')
                with open("login.json", "w", encoding='utf-8') as file:
                    file.write('')
                with open("data.json", "w", encoding='utf-8') as file:
                    file.write('')
                with open("counts.json", "w", encoding='utf-8') as file:
                    file.write('')
            except:
                print("Error Read")
            self.close()


    def gotoReportMy(self):
        self.welcome_window = MainReportSend()
        self.welcome_window.show()
    def gotoLocalReport(self):
        self.welcome_window = MainReportLocal()
        self.welcome_window.show()

    def show_help(self):
        import webbrowser
        if os.path.exists("data.json") and os.path.getsize("data.json") > 0:
            with open("data.json", "r", encoding='utf-8') as file:
                data = json.load(file)
                if data.get("host") != "":
                    webbrowser.open_new("https://"+data.get("host")+"/Help/index")

        else:
            # Displaying help message
            QMessageBox.information(self, "Help", "This is the help section.")

    def start_loading(self,loading_screen):
        # ایجاد شیء LoadDataThread و اتصال سیگنال‌ها
        self.load_thread = LoadDataThread(self.shift_widget)
        self.load_thread.finished.connect(loading_screen.close)
        self.load_thread.finished.connect(self.show)
        self.load_thread.start()

class ProfileWidget(QWidget):
    TimeStart="not started"
    UserName=""
    def __init__(self):
        super().__init__()
        self.language = langHandel("panel")
        TimeStart = self.language.get_value("started")
        if os.path.exists("login.json") and os.path.getsize("login.json") > 0:
            with open("login.json", "r", encoding='utf-8') as file:
                login = json.load(file)
                if login.get("data") != "":
                    self.UserName =  login.get("data")
        # Set widget properties
        self.setMinimumWidth(200)
        self.setStyleSheet("background-color: #F0F0F0; border-radius: 10px; padding: 10px;")

        # Main layout
        main_layout = QVBoxLayout(self)
        self.setLayout(main_layout)


        #Profile Layout
        profile_layout = QHBoxLayout()
        main_layout.addLayout(profile_layout)

        UserName_layout = QHBoxLayout()
        main_layout.addLayout(UserName_layout)

        # Load profile picture
        profile_picture = QLabel(self)
        profile_picture.setAlignment(Qt.AlignCenter)
        profile_picture.setPixmap(QPixmap("avatar.png").scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation))

        # User name label
        self.username_label = QLabel(self.UserName)
        self.username_label.setAlignment(Qt.AlignCenter)
        self.username_label.setStyleSheet("color: black; font-size:14px;")
        self.username_label.setFont(QFont("Arial", 12))
        profile_layout.addWidget(profile_picture)
        UserName_layout.addWidget(self.username_label)


        # Add profile widgets to profile box
        clickRow_layout = QVBoxLayout()
        clickRow_layout.setAlignment(Qt.AlignTop)
        main_layout.addLayout(clickRow_layout)

        click_layout = QHBoxLayout()
        click_layout.setAlignment(Qt.AlignTop)
        clickRow_layout.addLayout(click_layout)

        self.mouse_label = QLabel(self.language.get_value( "MouseclickDis"), self)
        self.keyboard_label = QLabel(self.language.get_value( "KeyboardclickDis"), self)
        self.mouse_label.setStyleSheet("color: black; font-weight: bold;font-size:10px;")
        self.keyboard_label.setStyleSheet("color: black; font-weight: bold;font-size:10px;")



        click_layout.addWidget(self.mouse_label)
        click_layout.addWidget(self.keyboard_label)

        #setStart Time Start
        TimeRow_layout = QVBoxLayout()
        TimeRow_layout.setAlignment(Qt.AlignTop)
        main_layout.addLayout(TimeRow_layout)

        timeHor_layout = QHBoxLayout()
        clickRow_layout.addLayout(timeHor_layout)

        self.Start_label = QLabel(self.language.get_value( "shift"), self)
        self.Start_Time_label = QLabel(self.TimeStart,self)
        self.Start_label.setStyleSheet("color: black; font-weight: bold; text-align: center; ")
        self.Start_Time_label.setStyleSheet("color: black; font-weight: bold;text-align: center;")

        self.Start_Time_label.setAlignment(Qt.AlignCenter)
        timeHor_layout.addWidget(self.Start_label)
        timeHor_layout.addWidget(self.Start_Time_label)






    def update_counts(self, mouse_clicks, keyboard_clicks):
        #print(mouse_clicks)
        #print(keyboard_clicks)
        if mouse_clicks>0 or keyboard_clicks>0:
            self.mouse_label.setText(self.language.get_value( "MouseclickEn"))
            self.keyboard_label.setText(self.language.get_value( "KeyboardclickEn"))
        else:
            self.mouse_label.setText(self.language.get_value( "MouseclickDis"))
            self.keyboard_label.setText(self.language.get_value( "KeyboardclickDis"))

    def update_Time(self, Text):
        self.Start_Time_label.setText(Text)

class CenterAlignDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        super(CenterAlignDelegate, self).__init__(parent)

    def paint(self, painter, option, index):
        option.displayAlignment = Qt.AlignCenter | Qt.AlignVCenter
        super(CenterAlignDelegate, self).paint(painter, option, index)
class ShiftWidget(QWidget):
    # اطلاعات پایه
    shiftId = 0
    stateUser = "Status: Active"
    timeStarted = "not started"
    taskList =[]
    projectList=[]


    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        # Set widget properties
        self.setStyleSheet("")

        # Main layout
        main_layout = QVBoxLayout(self)
        self.setLayout(main_layout)
        self.language = langHandel("panel")
        stateUser = self.language.get_value( "Status")
        timeStarted = self.language.get_value( "started")
        # Project and Task Selection Boxes (50% each)
        project_task_layout = QHBoxLayout()
        project_task_layout.setAlignment(Qt.AlignTop)
        main_layout.addLayout(project_task_layout)


        self.project_combo = QComboBox()
        self.project_combo.setEditable(True)
        project_combo_edit = self.project_combo.lineEdit()
        project_combo_edit.setAlignment(Qt.AlignCenter)
        project_combo_edit.setReadOnly(True)
        self.project_combo.addItem(self.language.get_value( "project"))
        #self.project_combo.activated.connect(self.show_project_dialog)

        self.task_combo = QComboBox()
        self.task_combo.setEditable(True)
        task_combo_edit = self.task_combo.lineEdit()
        task_combo_edit.setAlignment(Qt.AlignCenter)
        task_combo_edit.setReadOnly(True)
        self.task_combo.addItem(self.language.get_value( "task"))
        #self.task_combo.activated.connect(self.show_task_dialog)


        center_align_delegate = CenterAlignDelegate()
        self.project_combo.setItemDelegate(center_align_delegate)
        self.task_combo.setItemDelegate(center_align_delegate)

        center_align_delegate = CenterAlignDelegate()
        self.project_combo.setItemDelegate(center_align_delegate)
        self.task_combo.setItemDelegate(center_align_delegate)

        self.project_combo.setStyleSheet(" text-align: center;  ")
        self.task_combo.setStyleSheet("  text-align: center;  ")

        project_line_edit = self.project_combo.lineEdit()
        if project_line_edit is not None:
            project_line_edit.setAlignment(Qt.AlignCenter)

        task_line_edit = self.task_combo.lineEdit()
        if task_line_edit is not None:
            task_line_edit.setAlignment(Qt.AlignCenter)

        main_layout.addWidget(self.project_combo)
        main_layout.addWidget(self.task_combo)



        # End time widgets
        self.button = QPushButton(self.language.get_value( "submitReport"))
        self.button.clicked.connect(self.SendReport)
        self.button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        main_layout.addWidget(self.button)



        self.online_label = QLabel(self.stateUser)
        self.online_label.setAlignment(Qt.AlignCenter)
        self.online_label.setStyleSheet("  font-weight: bold;font-size:14px")
        main_layout.addWidget(self.online_label)
        # Shift control buttons
        control_layout = QHBoxLayout()
        control_layout.setAlignment(Qt.AlignTop)
        main_layout.addLayout(control_layout)

        self.start_button = QPushButton(self.language.get_value( "startShift"))
        self.end_button = QPushButton(self.language.get_value( "endShift"))
        self.end_button.setEnabled(False)

        # Set button styles
        self.start_button.setStyleSheet(
            "font-size: 14px; border: 2px solid green; border-radius: 5px; padding: 5px;  ")
        self.end_button.setStyleSheet(
            "font-size: 14px;  border: 2px solid red; border-radius: 5px; padding: 5px;  ")

        control_layout.addWidget(self.start_button)
        control_layout.addWidget(self.end_button)

        # Connect button signals
        self.start_button.clicked.connect(self.start_shift)
        self.end_button.clicked.connect(self.end_shift)

        self.shift_thread = ShiftThread()
        self.shift_thread.count_updated.connect(self.update_counts)
        minutes = 2
        userId=0
        if os.path.exists("login.json") and os.path.getsize("login.json") > 0:
            with open("login.json", "r", encoding='utf-8') as file:
                login = json.load(file)
                if login.get("timer") != 0:
                    minutes = int(login.get("timer"))
                if login.get("id") != 0:
                    userId =  login.get("id")

        self.seconds = minutes * 60
        self.websocket_thread = WebSocketClientThread(user_id=userId, shift_widget=self)
        self.screenshot_thread = ScreenshotThread(interval=self.seconds, shift_widget=self)
        self.checkShift()
        # تعریف نمونه `ReportThread`
        self.report_thread = ReportThread(self)
        self.report_thread.finished.connect(self.on_report_finished)





    def checkShift(self):
        exist = False

        if os.path.exists("shift.json") and os.path.getsize("shift.json") > 0:
            with open("shift.json", "r", encoding='utf-8') as file:
                shift = json.load(file)
                if shift.get("data") != 0:
                    exist = True
        else:
            shift = {}
            exist = False

        if os.path.exists("counts.json") and os.path.getsize("counts.json") > 0:
            with open("counts.json", "r", encoding='utf-8') as file:
                content = file.read()
                if content:
                    clicks = json.loads(content)
                else:
                    clicks = {}
        else:
            clicks = {}
        if exist:
            try:
                self.websocket_thread.start()
            except Exception as e:
                print(f"Error: {e}")
            self.shiftId = shift.get("data")
            print(shift.get("data"))
            print(self.shiftId)
            self.parent.profile_widget.update_Time(str(shift.get("started")))

            self.parent.profile_widget.update_counts(clicks.get("mouse_clicks"), clicks.get("keyboard_clicks"))

            self.start_button.setEnabled(False)
            self.end_button.setEnabled(True)
            # Get current date/time and update start time label

            self.shift_thread.start()
            self.screenshot_thread.start()
            self.stateUser = self.language.get_value( "onShift")
            self.online_label.setText(self.language.get_value( "onShift"))

        else:
            self.stateUser = self.language.get_value( "WaitingStartShift")
            self.online_label.setText(self.language.get_value( "WaitingStartShift"))
        try:
            self.setProject()
        except:
            print("Error")
        try:
            self.setTask()
        except:
            print("Error")

    def SendReport(self):
        login=[]
        if os.path.exists("login.json") and os.path.getsize("login.json") > 0:
            with open("login.json", "r", encoding='utf-8') as file:
                login = json.load(file)
        if (login.get("accessClinetSendReport") == "access"):
            if len(self.taskList)>0 and len(self.projectList)>0:
                if self.shiftId!=0 :
                    dialog = ReportDialog(self.projectList,self.taskList,self.shiftId,self.project_combo.currentIndex(),self.task_combo.currentIndex())
                    if dialog.exec_() == QDialog.Accepted:
                        # Process the accepted data here
                        pass
                else:
                    self.update_status(self.language.get_value( "errorSubmitReport"))
            else:
                self.update_status(self.language.get_value( "errorProjectTask"))
        else:
            self.update_status(self.language.get_value( "errorAccessReports"))
    def setTask(self):
        with open("data.json", "r", encoding='utf-8') as file:
            data = json.load(file)

        host = "https://" + data.get("host")
        with open("login.json", "r", encoding='utf-8') as file:
            login = json.load(file)

        token = login.get("token")
        url = f"{host}/frogment/apis/GetTask"
        payload = {'Token': token, "ip": "",   "NameClinets": ""}
        headers = {
            "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
            "Content-Type": "application/x-www-form-urlencoded"
        }
        try:
            response = requests.request("POST", url,headers=headers, data=payload, verify=False)
            response.raise_for_status()

            if response.status_code == 200:
                self.taskList = response.json()
                if len(self.taskList)>0:
                    model = QStandardItemModel()
                    for item in self.taskList:
                        standard_item = QStandardItem(item["title"])
                        standard_item.setData(item["id"], Qt.UserRole)
                        model.appendRow(standard_item)
                    self.task_combo.setModel(model)
                else:
                    model = QStandardItemModel()
                    standard_item = QStandardItem(self.language.get_value( "task"))
                    standard_item.setData(0, Qt.UserRole)
                    model.appendRow(standard_item)
                    self.task_combo.setModel(model)
                return True
            else:
                print("Failed to Get Task")
                self.show_error(self.language.get_value( "errorInternet"),
                                self.language.get_value( "checkInternet"))
                return False
        except requests.exceptions.HTTPError:
            self.show_error(self.language.get_value("errorInternet"),
                            self.language.get_value("checkInternet"))
            return False
        except Exception:
            self.show_error(self.language.get_value("errorInternet"),
                            self.language.get_value("checkInternet"))
            return False
        #self.task_combo.addItem("Active Task: Task XYZ")

    def setProject(self):
        with open("data.json", "r", encoding='utf-8') as file:
            data = json.load(file)

        host = "https://" + data.get("host")
        with open("login.json", "r", encoding='utf-8') as file:
            login = json.load(file)

        token = login.get("token")
        url = f"{host}/frogment/apis/getProject"
        payload = {'Token': token, "Ip": "", "NameClinets": ""}
        headers = {
            "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
            "Content-Type": "application/x-www-form-urlencoded"
        }
        try:
            response = requests.request("POST", url,headers=headers, data=payload, verify=False)
            response.raise_for_status()

            if response.status_code == 200:
                self.projectList = response.json()
                if len( self.projectList)>0:
                    models = QStandardItemModel()
                    for item in self.projectList:
                        standard_item = QStandardItem(item["project"]["title"])
                        standard_item.setData(item["projectId"], Qt.UserRole)
                        models.appendRow(standard_item)
                    self.project_combo.setModel(models)
                else:
                    models = QStandardItemModel()
                    standard_item = QStandardItem( self.language.get_value( "project"))
                    standard_item.setData(0, Qt.UserRole)
                    models.appendRow(standard_item)
                    self.project_combo.setModel(models)
                return  True
            else:
                print("error get project")
                self.show_error(self.language.get_value("errorInternet"),
                                self.language.get_value("checkInternet"))

                return False

        except requests.exceptions.HTTPError:
            print("error 2")
            self.show_error(self.language.get_value("errorInternet"),
                            self.language.get_value("checkInternet"))

            return False
        except Exception:
            print("error 3")
            self.show_error(self.language.get_value("errorInternet"),
                            self.language.get_value("checkInternet"))

            return False
        # self.task_combo.addItem("Active Task: Task XYZ")

    def show_error(self, title, message):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setWindowTitle(title)
        msg.setText(message)
        msg.exec_()

    def show_Succ(self, title, message):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setWindowTitle(title)
        msg.setText(message)
        msg.exec_()

    def show_project_dialog(self, index):
        dialog = QDialog(self)
        dialog.setWindowTitle( self.language.get_value( "activeProject"))
        dialog.setMinimumSize(300, 100)

        combo_box = QComboBox(dialog)
        combo_box.addItem(self.language.get_value( "project"))
        combo_box.move(20, 20)

        # Data for Project
        project_model = QStandardItemModel()
        for item in self.projectList:
            standard_item = QStandardItem(item["project"]["title"])
            standard_item.setData(item["projectId"], Qt.UserRole)
            project_model.appendRow(standard_item)
        combo_box.setModel(project_model)



        confirm_button = QPushButton(self.language.get_value( "confirmation"), dialog)
        confirm_button.move(200, 20)
        confirm_button.clicked.connect(dialog.accept)

        dialog.exec_()
        if dialog.result() == QDialog.Accepted:
            self.project_combo.setCurrentIndex(index)

    def show_task_dialog(self, index):
        dialog = QDialog(self)
        dialog.setWindowTitle(self.language.get_value( "activeTask"))
        dialog.setMinimumSize(300, 100)

        combo_box = QComboBox(dialog)
        combo_box.addItem(self.language.get_value( "task"))
        combo_box.move(20, 20)

        # Data for Task
        task_model = QStandardItemModel()
        for item in self.taskList:
            standard_item = QStandardItem(item["title"])
            standard_item.setData(item["id"], Qt.UserRole)
            task_model.appendRow(standard_item)
        combo_box.setModel(task_model)

        confirm_button = QPushButton(self.language.get_value( "confirmation"), dialog)
        confirm_button.move(200, 20)
        confirm_button.clicked.connect(dialog.accept)

        dialog.exec_()
        if dialog.result() == QDialog.Accepted:
            self.task_combo.setCurrentIndex(index)



    def start_shift(self):
        self.start_button.setEnabled(False)  # غیرفعال کردن دکمه شروع شیفت
        self.shift_worker = ShiftWorker('start')
        self.shift_worker.shift_started.connect(self.on_shift_started)
        self.shift_worker.update_status.connect(self.update_status)
        self.shift_worker.ShiftId.connect(self.update_shiftId)
        self.shift_worker.timeStarted.connect(self.update_timeStarted)
        self.shift_worker.start()
        self.online_label.setText(self.language.get_value( "startingshift"))
        self.websocket_thread.start()

    def end_shift(self):
        print("Ending shift")
        self.end_button.setEnabled(False)  # غیرفعال کردن دکمه پایان شیفت
        self.online_label.setText(self.language.get_value( "recordingshifts"))
        self.shift_worker = ShiftWorker('end')
        self.shift_worker.shift_ended.connect(self.on_shift_ended)
        self.shift_worker.update_status.connect(self.update_status)
        self.shift_worker.ShiftId.connect(self.update_shiftId)
        self.shift_worker.timeStarted.connect(self.update_timeStarted)

        self.shift_worker.start()



    def on_shift_started(self, success):

        if success:
            self.start_button.setEnabled(False)  # دکمه شروع شیفت غیرفعال باقی می‌ماند
            self.end_button.setEnabled(True)
            self.shift_thread.start()
            self.screenshot_thread=ScreenshotThread(interval=self.seconds,shift_widget=self)
            self.screenshot_thread.start()
        else:
            self.start_button.setEnabled(True)  # دکمه شروع شیفت دوباره فعال می‌شود
            self.online_label.setText(self.language.get_value( "errorshiftendEx"))
            self.end_button.setEnabled(False)

    def on_shift_ended(self, success):
        if success:
            self.start_button.setEnabled(True)
            self.end_button.setEnabled(False)
            self.shift_thread.mouse_clicks=0
            self.shift_thread.keyboard_clicks=0
            self.update_counts(0, 0)
            self.shift_thread.stop()
            self.screenshot_thread.stop()
        else:
            self.start_button.setEnabled(False)
            self.end_button.setEnabled(True)
            self.online_label.setText(self.language.get_value( "errorshiftendEx"))

    def update_status(self, status):
        self.online_label.setText(status)

    def update_shiftId(self, shiftId):
        self.shiftId =shiftId

    def update_timeStarted(self, timerStarted):
        self.parent.profile_widget.update_Time(timerStarted)
    def on_report_finished(self, result):
        if result:
            print("گزارش‌ها با موفقیت ارسال شدند.")
        else:
            print("خطا در ارسال گزارش‌ها.")

    def update_counts(self, mouse_clicks, keyboard_clicks):
        self.parent.profile_widget.update_counts(mouse_clicks, keyboard_clicks)
        self.save_counts()

    def save_counts(self):
        counts = {
            'mouse_clicks': self.shift_thread.mouse_clicks,
            'keyboard_clicks': self.shift_thread.keyboard_clicks
        }
        with open('counts.json', 'w') as file:
            json.dump(counts, file)


def get_client_info():
    # Get the hostname
    hostname = socket.gethostname()

    # Get the IP address
    ip_address = socket.gethostbyname(hostname)
    # Create a dictionary with the information
    client_info = {
        "hostname": hostname,
        "ip_address": ip_address
    }

    return client_info
class ReportDialog(QDialog):
    def __init__(self, modelProject, modelTask, ShiftId,indexProject,indexTask):
        super().__init__()
        print(modelProject)
        print(modelTask)
        print(ShiftId)
        self.language = langHandel("panel")
        self.setWindowTitle(self.language.get_value( "activityReport"))
        self.setMinimumSize(400, 300)

        layout = QVBoxLayout()

        # Title
        self.title_label = QLabel(self.language.get_value( "activeProject"))
        layout.addWidget(self.title_label)

        # Project Combo Box
        self.project_combo = QComboBox()

        self.project_combo.setEditable(True)
        task_combo_edit2 = self.project_combo.lineEdit()
        task_combo_edit2.setAlignment(Qt.AlignCenter)
        task_combo_edit2.setReadOnly(True)
        self.project_combo.addItem(self.language.get_value( "project"))
        layout.addWidget(self.project_combo)

        # Task Combo Box
        self.task_combo = QComboBox()

        self.task_combo.setEditable(True)
        task_combo_edit2 = self.task_combo.lineEdit()
        task_combo_edit2.setAlignment(Qt.AlignCenter)
        task_combo_edit2.setReadOnly(True)
        self.task_combo.addItem(self.language.get_value( "task"))
        layout.addWidget(self.task_combo)

        # Data for Project
        project_model = QStandardItemModel()
        for item in modelProject:
            standard_item = QStandardItem(item["project"]["title"])
            standard_item.setData(item["projectId"], Qt.UserRole)
            project_model.appendRow(standard_item)
        self.project_combo.setModel(project_model)

        # Data for Task
        task_model = QStandardItemModel()
        for item in modelTask:
            standard_item = QStandardItem(item["title"])
            standard_item.setData(item["id"], Qt.UserRole)
            task_model.appendRow(standard_item)
        self.task_combo.setModel(task_model)

        # Text input for report
        self.report_input = QTextEdit()
        self.report_input.setPlaceholderText(self.language.get_value( "inputReport"))
        layout.addWidget(self.report_input)

        # Confirm Button
        confirm_button = QPushButton(self.language.get_value( "sendReport"))
        confirm_button.clicked.connect(self.submit_report)
        layout.addWidget(confirm_button)
        self.project_combo.setCurrentIndex(indexProject)
        self.task_combo.setCurrentIndex(indexTask)
        self.setLayout(layout)

    def submit_report(self):
        selected_project_index = self.project_combo.currentIndex()
        selected_task_index = self.task_combo.currentIndex()

        selected_project_id = self.project_combo.itemData(selected_project_index, Qt.UserRole)
        selected_task_id = self.task_combo.itemData(selected_task_index, Qt.UserRole)

        report_text = self.report_input.toPlainText()

        # Here you can add the code to process the report
        print(f"Project ID: {selected_project_id}")
        print(f"Task ID: {selected_task_id}")
        print(f"Report: {report_text}")
        self.title_label.setText(self.language.get_value( "wait"))
        with open("data.json", "r", encoding='utf-8') as file:
            data = json.load(file)

        # دریافت فیلد host
        host = "https://" + data.get("host")

        with open("login.json", "r", encoding='utf-8') as file:
            login = json.load(file)

        # دریافت فیلد token
        token = login.get("token")
        url = f"{host}/frogment/apis/SetTextReport"

        dataActive = {
            'ProjectId': selected_project_id,
            'TaskId': selected_task_id,
            'Text': report_text,
            'Token':token
        }

        try:
            headers = {
                "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
                "Content-Type": "application/x-www-form-urlencoded"
            }
            # ارسال داده‌ها به سرور
            response = requests.request("POST", url,headers=headers, data=dataActive, verify=False)

            if response.status_code == 200:
                response_json = response.json()
                if(response_json["status"]=="200"):
                    self.title_label.setText(self.language.get_value( "successfullyReport"))
                    self.accept()
                else:
                    self.title_label.setText(response_json["results"])


            else:
                self.title_label.setText(self.language.get_value( "errorSendReport"))

        except requests.RequestException as e:
            self.title_label.setText(self.language.get_value( "errorSendReport"))

        except Exception as e:
            self.title_label.setText(self.language.get_value( "errorSendReport"))
        # Close the dialog

class DetailDialogProfile(QDialog):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("EM Profile")
        self.language = langHandel("panel")
        user32 = ctypes.windll.user32
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        left = screen_width - 730
        top = screen_height - 420
        self.setGeometry(left, top, 400, 400)
        self.setWindowIcon(QIcon('ixo.png'))

        layout = QVBoxLayout()
        with open("login.json", "r", encoding='utf-8') as file:
            login = json.load(file)
        exist=False
        if os.path.exists("shift.json") and os.path.getsize("shift.json") > 0:
            with open("shift.json", "r", encoding='utf-8') as file:
                shift = json.load(file)
                if shift.get("data") != 0:
                    exist = True
        else:
            shift = {}
            exist = False
        label_shift=""
        if exist:
            label_shift=self.language.get_value( "onshift")
        else:
            label_shift = self.language.get_value( "noshift")
        token = login.get("token")
        email = login.get("data")
        accessClinetSendReport = login.get("accessClinetSendReport")
        profile_picture = QLabel(self)
        profile_picture.setAlignment(Qt.AlignCenter)
        profile_picture.setPixmap(QPixmap("avatar.png").scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation))

        title_label = QLabel(self.language.get_value("email")+f" : {email}")
        title_label.setStyleSheet("font-size:18px")
        stateShift = QLabel(self.language.get_value("shiftStatus") + f" : {label_shift}")
        stateShift.setStyleSheet("font-size:15px")
        caption_label = QLabel(self.language.get_value("token")+f" : {token}")
        caption_label.setStyleSheet("font-size:15px")
        create_time_label = QLabel(self.language.get_value("AccessReportsSubmission")+ f" : {accessClinetSendReport}")
        create_time_label.setStyleSheet("font-size:15px")

        layout.addWidget(profile_picture)
        layout.addWidget(title_label)
        layout.addWidget(stateShift)
        layout.addWidget(caption_label)

        layout.addWidget(create_time_label)

        self.setLayout(layout)



class LoadingScreen(QDialog):
    def __init__(self):
        super().__init__()
        user32 = ctypes.windll.user32
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        left = screen_width - 300
        top = screen_height - 250
        self.language = langHandel("panel")
        self.setWindowTitle("EM Loading")
        self.setGeometry(left, top, 200, 100)
        self.setWindowIcon(QIcon('ixo.png'))
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint)

        layout = QVBoxLayout()

        # ایجاد QLabel برای تصویر
        self.image_label = QLabel(self)
        pixmap = QPixmap('logoStart.png')  # مسیر به تصویر خود را تنظیم کنید
        self.image_label.setPixmap(pixmap)
        self.image_label.setAlignment(Qt.AlignCenter)  # تراز کردن تصویر به مرکز

        # ایجاد QLabel برای متن
        self.text_label = QLabel(self.language.get_value( "wait"), self)
        self.text_label.setAlignment(Qt.AlignCenter)  # تراز کردن متن به مرکز
        self.text_label_w = QLabel(self.language.get_value( "checking"), self)
        self.text_label_w.setAlignment(Qt.AlignCenter)  # تراز کردن متن به مرکز


        # اضافه کردن QLabel ها به layout
        layout.addWidget(self.image_label)
        layout.addWidget(self.text_label)
        layout.addWidget(self.text_label_w)

        self.setLayout(layout)



class LoadDataThread(QThread):
    finished = pyqtSignal(bool)  # سیگنال برای اتمام عملیات

    def __init__(self, shift_widget):
        super().__init__()
        self.shift_widget = shift_widget

    def run(self):
        try:
            self.shift_widget.setProject()
            self.shift_widget.setTask()
            self.refreshAuth()
        except Exception as e:
            print(f"Error loading data: {e}")
        self.finished.emit(True)


    def refreshAuth(self ):
        try:
            # بررسی وجود و اندازه فایل data.json
            if os.path.exists("data.json") and os.path.getsize("data.json") > 0:
                with open("data.json", "r", encoding='utf-8') as file:
                    content = file.read()
                    if content:
                        login = json.loads(content)  # استفاده از json.loads به جای json.load
                    else:
                        login = {}

            # بررسی وجود و اندازه فایل login.json
            if os.path.exists("login.json") and os.path.getsize("login.json") > 0:
                with open("login.json", "r", encoding='utf-8') as file:
                    content = file.read()
                    if content:
                        login_data = json.loads(content)  # استفاده از json.loads به جای json.load
                    else:
                        login_data = {}
            url = f"https://{login.get('host')}/frogment/apis/Auth"
            headers = {
                "User-Agent": "Your User Agent",  # در صورت نیاز به استفاده از Bearer Token
                "Content-Type": "application/x-www-form-urlencoded"
            }

            payload = {
                'Token': login_data.get('token'),
                'Ip': "",
                'NameClinets': "",
            }

            try:
                response = requests.post(url, headers=headers, data=payload, verify=False)
                print(response)
                if response.status_code == 200:
                    # تبدیل پاسخ به فرمت JSON
                    response_json = response.json()
                    with open("login.json", "w", encoding='utf-8') as file:
                        json.dump(response_json, file, ensure_ascii=False, indent=4)
                    return True
                else:
                    return False

            except requests.exceptions.HTTPError as err:
                print(err)
                return False
            except Exception as err:
                print(err)
                return False
        except Exception as e:
            print(f"Error refresh data: {e}")

class ThemeSelectorDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.language = langHandel("panel")
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Select Theme')
        user32 = ctypes.windll.user32
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        left = screen_width - 730
        top = screen_height - 420
        self.setWindowTitle("EM Dashboard")
        self.setGeometry(left, top, 300, 150)
        self.setWindowIcon(QIcon('ixo.png'))

        layout = QVBoxLayout()

        # Label
        self.label = QLabel(self.language.get_value( "selectThem"), self)
        layout.addWidget(self.label)

        # ComboBox for themes
        self.combo_box = QComboBox(self)
        # Add your themes here
        themes = [
            "dark_blue", "dark_amber", "dark_cyan", "dark_lightgreen",
            "dark_pink", "dark_purple", "dark_teal", "dark_red", "dark_yellow",
            "light_blue", "light_amber", "light_cyan", "light_lightgreen",
            "light_pink", "light_purple", "light_teal", "light_red", "light_yellow"
        ]
        self.combo_box.addItems(themes)
        self.combo_box.setEditable(True)
        task_combo_edit2 = self.combo_box.lineEdit()
        task_combo_edit2.setAlignment(Qt.AlignCenter)
        task_combo_edit2.setReadOnly(True)
        layout.addWidget(self.combo_box)

        # OK button
        self.ok_button = QPushButton(self.language.get_value( "confirmation"), self)
        self.ok_button.clicked.connect(self.save_selection)
        layout.addWidget(self.ok_button)

        self.setLayout(layout)

    def save_selection(self):
        selected_theme = self.combo_box.currentText()
        # Save the selected theme to a JSON file
        with open('selected_theme.json', 'w') as f:
            json.dump({'selected_theme': selected_theme}, f)
        self.accept()

class LanguageSelectorDialog(QDialog):
    def __init__(self):
        super().__init__()
        user32 = ctypes.windll.user32
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        left = screen_width - 430
        top = screen_height - 250

        self.setWindowTitle("Select Language")
        self.setGeometry(left, top, 300, 150)
        self.setWindowIcon(QIcon('ixo.png'))
        self.lang_dir = "lang"
        self.initUI()

    def initUI(self):
        # تنظیمات صفحه

        # عنوان
        self.label = QLabel('Choose the desired language', self)
        self.setStyleSheet("font-size:15px")
        # لیست انتخاب زبان
        self.comboBox = QComboBox(self)
        self.populate_languages()

        # دکمه تایید
        self.button = QPushButton('confirmation', self)
        self.button.clicked.connect(self.on_confirm)

        # چیدمان صفحه
        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.comboBox)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def populate_languages(self):
        # خواندن فایل‌ها از پوشه lang
        files = os.listdir(self.lang_dir)
        languages = [os.path.splitext(f)[0] for f in files if f != 'lang.json']
        self.comboBox.addItems(languages)

    def on_confirm(self):
        selected_language = self.comboBox.currentText()
        if selected_language:
            QMessageBox.information(self, 'was selected', f'Selected language : {selected_language}')
            # ذخیره زبان انتخاب شده در فایل lang.json
            lang_data = {"language": selected_language}
            with open(os.path.join(self.lang_dir, 'lang.json'), 'w', encoding='utf-8') as lang_file:
                json.dump(lang_data, lang_file, ensure_ascii=False, indent=4)
            self.accept()
        else:
            QMessageBox.warning(self, 'warning', 'No language is selected')


