# Zeiterfassung

# User bezogene Funktionen

import os
import datetime
import time
import json
import shutil
import re

from definitions import userfolder, scriptpath, usersettingsfilename, photofilename, status_in, status_out

# Benutzerklasse

class user:
    def __init__(self, name):
        self.userfolder =  f"{scriptpath}/{userfolder}/{name}"
        self.settingsfile = f"{self.userfolder}/{usersettingsfilename}"
        self.photofile = f"{self.userfolder}/{photofilename}"

        # Stammdaten einlesen
        try:
            with open(self.settingsfile) as json_file:
                data = json.load(json_file)

        except:
            print("Fehler beim Erstellen des Datenarrays.")
            #Hier muss noch Fehlerbehandlungcode hin

        self.password = data["password"]
        self.workhours = data["workhours"]
        self.username = data["username"]
        self.fullname = data["fullname"]

    def get_stamp_file(self, time_stamp=None):
        if time_stamp == None:
            year = str(datetime.datetime.now().year)
            month = str(datetime.datetime.now().month)
        else:
            year = str(datetime.datetime.fromtimestamp(time_stamp).year)
            month = str(datetime.datetime.fromtimestamp(time_stamp).month)
        completepath = f"{self.userfolder}/{year}-{month}"
        return completepath

    def timestamp(self, stamptime=-1):

        if stamptime == -1:
            stamptime = time.time()
        timestamp = int(stamptime)

        filename = f"{self.get_stamp_file(time_stamp=stamptime)}.txt"

        try:
            # Öffne die Datei im Anhang-Modus ('a')
            with open(filename, 'a') as file:
                # Schreibe den Timestamp in die Datei und füge einen Zeilenumbruch hinzu
                file.write(f"{timestamp}\n")
            file.close()
        except FileNotFoundError:
            # Fehlende Verzeichnisse anlegen
            folder_path = os.path.dirname(filename)
            os.makedirs(folder_path, exist_ok=True)
            self.timestamp()

        # Nach zugehörigem JSON-File suchen und bei Bedarf anlegen
        try:
            json_filename = f"{self.get_stamp_file()}.json"
            with open(json_filename, 'r') as json_file:
                pass
        except:
            dict = { }
            dict["archived"] = 0
            dict["total_hours"] = 0

            json_dict = json.dumps(dict, indent=4)
            with open(json_filename, 'w') as json_file:
                json_file.write(json_dict)

    def stamp_status(self):
        try:
            # Öffne die Datei im Lese-Modus ('r')
            with open(f"{self.get_stamp_file()}.txt", 'r') as file:
                # Zähle die Zeilen
                lines = file.readlines()
            file.close()
        except FileNotFoundError:
            print(f"Die Datei {filename} wurde nicht gefunden.")
        if len(lines)== 0:
            print(f"Keine Einträge")
        elif len(lines) % 2 == 0:
            return (status_out)
        else:
            return (status_in)

    def last_2_timestmaps(self):

        with open(f"{self.get_stamp_file()}.txt", 'r') as file:
            lines = file.readlines()
        file.close()

        if len(lines) > 2:
            second_last_line = int(lines[-2])
            last_line = int(lines[-1])
            last_2_timestmaps = [second_last_line, last_line]
            return last_2_timestmaps

        elif len(lines) == 1:
            return int(lines[0])
        else:
            return -1

    def write_settings(self):
        dict = { }
        dict["username"] = (self.username)
        dict["fullname"] = (self.fullname)
        dict["password"] = (self.password)
        dict["workhours"] = (self.workhours)

        json_dict = json.dumps(dict, indent=4)

        with open(self.settingsfile, "w") as outputfile:
            outputfile.write(json_dict)

        pathcheck = self.userfolder
        pathcheck = pathcheck.removeprefix(f"{scriptpath}/{userfolder}/")

        if pathcheck != self.username:
            os.rename(self.userfolder, f"{scriptpath}/{userfolder}/{self.username}")

    def del_user(self):
        shutil.rmtree(self.userfolder)

    def get_starting_day(self):
        starting_date = list(self.workhours)
        starting_date.sort()
        year = str(starting_date[0])[:4]
        month = str(starting_date[0])[5:7]
        day = str(starting_date[0])[8:10]

        return (year, month, day)

    def get_years(self):
        years = [ ]

        # Aktuelles Jahr bestimmen
        year_now = int(datetime.datetime.fromtimestamp(time.time()).strftime('%Y'))

        for i in range(int(self.get_starting_day()[0]), year_now + 1):
            years.append(str(i))

        for file in os.listdir(self.userfolder):
            if re.match(r"\d{4}-\d{1,2}\.json", file):
                year = file.split("-")[0]
                if year not in years:
                    years.append(year)

        years.sort()
        return years

    def get_months(self, year):
        available_months = [ ]

        # Anfangsdatum bestimmen
        start_year = int(self.get_starting_day()[0])
        start_month = int(self.get_starting_day()[1])
        year_now = int(datetime.datetime.now().year)
        month_now = int(datetime.datetime.now().month)

        if start_year == int(year):

            if start_year == year_now:
                for i in range(start_month, month_now + 1):
                    available_months.append(i)
            elif start_year < year_now:
                for i in range(start_month, 13):
                    available_months.append(i)
        else:
            if int(year) == year_now:
                for i in range(1, month_now + 1):
                    available_months.append(i)
            elif int(year) < year_now:
                for i in range(1, 13):
                    available_months.append(i)

        for file in os.listdir(self.userfolder):

            if re.match(r"\d{4}-\d{1,2}\.json", file):
                if file.split("-")[0] == str(year):
                    month = int(file.split("-")[1].split(".")[0])
                    if month not in available_months:
                        available_months.append(month)
        available_months.sort()
        return(available_months)

    def get_timestamps(self, year, month):
        try:
            with open(f"{self.userfolder}/{year}-{month}.txt", "r") as file:
                timestamps = file.readlines()
            timestamps.sort()
            return timestamps
        except:
            timestamps = [ ]
            return timestamps

    def write_edited_timestamps(self, timestamps, year, month):
        with open(f"{self.userfolder}/{year}-{month}.txt", "w") as file:
            file.write(''.join(timestamps))

    def archive_hours(self, year, month):
        pass

    def get_last_months_overtime(self, year, month):
        try:
            if int(month) == 1:
                year = str(int(year) - 1)
                month = str(12)
            else:
                month = str(int(month) - 1)
            with open(f"{self.userfolder}/{year}-{month}.json", "r") as json_file:
                json_data = json.load(json_file)

            if json_data["archived"] == 1:
                overtime = int(json_data["overtime"])
                return overtime
            else:
                return 0
        except:
            return 0

    def get_absence(self, year, month):
        try:
            with open(f"{self.userfolder}/{year}-{month}.json", "r") as json_file:
                json_data = json.load(json_file)
            absence = json_data["absence"]
            return absence
        except:
            return { }

    def update_absence(self, year, month, day, absence_type):
        try:
            with open(f"{self.userfolder}/{int(year)}-{int(month)}.json", "r") as json_file:
                json_data = json.load(json_file)
        except:
            with open(f"{self.userfolder}/{year}-{month}.json", "w") as json_file:
                json_data = { }
                json_data["archived"] = 0
                json_data["overtime"] = 0
                json_dict = json.dumps(json_data, indent=4)
                json_file.write(json_dict)
        try:
            json_data["absence"][str(int(day))] = absence_type
        except:
            json_data.update({ "absence": { str(int(day)): absence_type}})
        json_dict = json.dumps(json_data, indent=4)

        with open(f"{self.userfolder}/{int(year)}-{int(month)}.json", "w") as json_file:
            json_file.write(json_dict)

    def del_absence(self, year, month, day):
        with open(f"{self.userfolder}/{int(year)}-{int(month)}.json", "r") as json_file:
            json_data = json.load(json_file)

        del json_data["absence"][str(day)]
        json_dict = json.dumps(json_data, indent=4)

        with open(f"{self.userfolder}/{int(year)}-{int(month)}.json", "w") as json_file:
            json_file.write(json_dict)

    def get_day_workhours(self, year, month, day):
        workhour_entries = list(self.workhours)
        workhour_entries.sort()
        day_to_check = datetime.datetime(int(year), int(month), int(day))

        for entry in reversed(workhour_entries):

            entry_split = entry.split("-")
            entry_dt = datetime.datetime(int(entry_split[0]), int(entry_split[1]), int(entry_split[2]))

            if entry_dt <= day_to_check:
                weekday = day_to_check.strftime("%w")
                if int(weekday) == 0:
                    weekday = str(7)
                hours_to_work = self.workhours[entry][weekday]
                break
            else:
                # Wenn vor Einstellungsdatum -1 ausgeben
                hours_to_work = -1
        return hours_to_work

    def get_vacation_claim(self, year, month, day):
        workhour_entries = list(self.workhours)
        workhour_entries.sort()
        day_to_check = datetime.datetime(int(year), int(month), int(day))

        claim = -1

        for entry in reversed(workhour_entries):

            entry_split = entry.split("-")
            entry_dt = datetime.datetime(int(entry_split[0]), int(entry_split[1]), int(entry_split[2]))

            if entry_dt <= day_to_check:
                claim = self.workhours[entry]["vacation"]
                break

        return claim

    def delete_photo(self):
        os.remove(self.photofile)

# Benutzer auflisten
def list_users():
    users = [d for d in os.listdir(userfolder) if os.path.isdir(os.path.join(userfolder, d))]
    users.sort()
    return users

