import os
from wsgiref import headers

from faker import Faker
import random
import csv
from datetime import datetime, timedelta

fake = Faker('pl_PL')


def generate_dynamic_motives(num_motives):
    emotions = [
        "Zemsta", "Zazdrość", "Chciwość", "Strach", "Obsesja",
        "Wściekłość", "Rozpacz", "Pycha", "Miłość", "Nienawiść",
        "Gniew", "Smutek", "Radość", "Zaskoczenie", "Wstyd",
        "Pogarda", "Zawiść", "Lęk", "Nadzieja", "Zachwyt"
    ]

    targets = [
        "za zdradę", "o władzę", "o bogactwo", "o tajemnicę",
        "o honor", "o miłość", "o spadek", "o pozycję",
        "o wolność", "o zemstę", "o prawdę", "o sprawiedliwość",
        "o przetrwanie", "o uznanie", "o bezpieczeństwo",
        "o sukces", "o kontrolę", "o dominację", "o szacunek", "o lojalność"
    ]

    contexts = [
        "w rodzinie", "w pracy", "w gangu", "w społeczeństwie",
        "w ukryciu", "w afekcie", "w desperacji", "w spisku",
        "w rywalizacji", "w sekrecie", "w szkole", "w polityce",
        "w biznesie", "w sądzie", "w mediach",
        "w wojsku", "w religii", "w przyjaźni", "w miłości", "w podróży"
    ]

    details = [
        "spowodowana długoletnią urazą", "wywołana nagłym impulsem",
        "planowana od miesięcy", "będąca wynikiem zdrady zaufania",
        "napędzana obsesyjnym pragnieniem", "ukryta pod pozorami przyjaźni",
        "wynikająca z tragicznego nieporozumienia", "podsycana plotkami",
        "zrealizowana w chwili słabości", "oparta na fałszywych przesłankach",
        "wzmacniana przez manipulacje", "podtrzymywana przez strach",
        "zainspirowana przez przeszłość", "wzmocniona przez zazdrość",
        "podsycana przez ambicję", "napędzana przez nienawiść",
        "ukryta przez lata", "wzmacniana przez kłamstwa", "podtrzymywana przez zemstę", "zainspirowana przez miłość"
    ]

    motives = []
    for i in range(num_motives):
        emotion = random.choice(emotions)
        target = random.choice(targets)
        context = random.choice(contexts)
        detail = random.choice(details)

        motive_name = f"{emotion} {target}"
        motive_details = f"{emotion} {target} {context} {detail}"

        motives.append([
            motive_name,
            motive_details
        ])

    headers = ['motyw', 'szczegoly']

    writeToFile(headers, motives, 'motyw.csv')

    return motives


def generate_status_sprawy_data(num_records):
    status_names = [
        "Oczekująca", "W toku", "Zakończona", "Anulowana", "Odroczona"
    ]

    # completion_methods = [
    #     "Sukces", "Niepowodzenie", "Anulowanie", "Przełożenie", "Inne"
    # ]

    data = []
    for i in range(num_records):
        name = random.choice(status_names)
        date = datetime.now() - timedelta(days=random.randint(0, 365))

        if name == "Zakończona":
            completion_method = random.choice(["Sukces", "Niepowodzenie"])
        elif name == "Anulowana":
            completion_method = "Anulowanie"
        else:
            completion_method = "Inne"

        data.append([
            name,
            date.strftime('%Y-%m-%d %H:%M:%S'),
            completion_method
        ])

    headers = ['nazwa', 'data', 'sposob_zakonczenia']

    writeToFile(headers, data, 'status_sprawy.csv')


def generate_pora_dnia(num_records):
    pora = ["Rano"], ["Dzień"], ["Obiad"], ["Wieczór"], ["Noc"]
    headers = ['nazwa']

    writeToFile(headers, pora, 'pora_dnia.csv')


def generate_czas(num_records):
    pory_dnia = {
        1: (6, 9),  # Rano: 6:00 - 8:59
        2: (9, 12),  # Dzień: 9:00 - 11:59
        3: (12, 15),  # Obiad: 12:00 - 14:59
        4: (15, 18),  # Wieczór: 15:00 - 17:59
        5: (18, 24)  # Noc: 18:00 - 23:59
    }
    data = []

    for i in range(num_records):
        id_pory_dnia = random.choice(list(pory_dnia.keys()))
        godzina_start, godzina_end = pory_dnia[id_pory_dnia]
        godzina = (datetime.min + timedelta(hours=random.randint(godzina_start, godzina_end - 1),
                                            minutes=random.randint(0, 59))).time()
        dzien = random.randint(1, 31)
        miesiac = random.randint(1, 12)
        rok = random.randint(2000, 2023)

        data.append([
            id_pory_dnia,
            dzien,
            miesiac,
            rok,
            godzina.strftime('%H:%M:%S')
        ])

    headers = ['id_pory_dnia', 'dzien', 'miesiac', 'rok', 'godzina']

    writeToFile(headers, data, 'czas.csv')


def generate_adres_sprawcy(num_records):
    data = []

    for _ in range(num_records):
        kraj = "Polska"
        ulica = fake.street_name()
        miasto = fake.city()
        kod_pocztowy = fake.postcode()

        data.append([
            ulica,
            miasto,
            kod_pocztowy,
            kraj
        ])

    headers = ['ulica', 'miasto', 'kod_pocztowy', 'kraj']
    writeToFile(headers, data, 'adres_sprawcy.csv')

def generate_adres_lokalizacji(num_records):
    data = []

    for _ in range(num_records):
        kraj = "Polska"
        ulica = fake.street_name()
        miasto = fake.city()
        kod_pocztowy = fake.postcode()

        data.append([
            ulica,
            miasto,
            kod_pocztowy,
            kraj
        ])

    headers = ['ulica', 'miasto', 'kod_pocztowy', 'kraj']
    writeToFile(headers, data, 'adres_lokalizacji.csv')

def generate_typy_lokalizacji(num_records):
    data = []
    typy = [
        "Mieszkanie", "Dom jednorodzinny", "Blok mieszkalny", "Biuro",
        "Magazyn", "Sklep", "Fabryka", "Parking", "Las", "Park",
        "Plaża", "Garaż", "Piwnica", "Strych", "Szkoła", "Szpital",
        "Kościół", "Dworzec", "Lotnisko", "Hotel"
    ]

    for _ in range(num_records):
        data.append([random.choice(typy)])

    headers = ['nazwa']
    writeToFile(headers, data, 'typy_lokalizacji.csv')

def generate_lokalizacje(num_records):
    data = []

    for _ in range(num_records):
        id_typu_lokalizacji = random.choice(range(1,20))
        id_adresu_lokalizacji = random.choice(range(1,8000))
        wspolrzedne = fake.local_latlng(country_code="PL", coords_only=True)

        data.append([
            id_typu_lokalizacji,
            id_adresu_lokalizacji,
            wspolrzedne[0],
        ])

    headers = ['id_typu_lokalizacji', 'id_adresu_lokalizacji', 'wspolrzedne']

    writeToFile(headers, data, 'lokalizacje.csv')

def generate_dane_osobowe(num_records):
    data = []

    for _ in range(num_records):
        imie = fake.first_name()
        nazwisko = fake.last_name()
        data_urodzenia_str = fake.date_of_birth(minimum_age=18, maximum_age=80).strftime('%Y-%m-%d')
        data_urodzenia = datetime.strptime(data_urodzenia_str, '%Y-%m-%d')
        plec = random.choice(['M', 'K'])
        pesel = fake.pesel(sex=plec, date_of_birth=data_urodzenia)
        narodowosc = random.choice([
            "Polska", "Niemiecka", "Francuska", "Włoska", "Hiszpańska",
            "Czeska", "Słowacka", "Węgierska", "Szwedzka", "Norweska",
            "Duńska", "Fińska", "Rosyjska", "Ukraińska", "Białoruska"
        ])

        data.append([
            pesel,
            imie,
            nazwisko,
            data_urodzenia.date(),
            plec,
            narodowosc
        ])

    headers = ["pesel", "imie", "nazwisko", "data_urodzenia", "plec", "narodowosc"]

    writeToFile(headers, data, 'dane_osobowe.csv')


def generate_sprawcy(num_records):
    data = []

    for i in range(num_records):
        id_danych = i+1
        id_adresu = i+1
        status_kryminalny = random.choice(["Tak", "Nie"])

        data.append([
            id_danych,
            id_adresu,
            status_kryminalny
        ])

    headers = ['id_danych', 'id_adresu', 'status_kryminalny']

    writeToFile(headers, data, 'sprawcy.csv')


def generate_lokalizacja_narzedzia(num_records):
    data = []

    for _ in range(num_records):
        miasto = fake.city()
        kod_pocztowy = fake.postcode()
        ulica = fake.street_name()
        numer_domu = fake.building_number().split('/')[0]

        data.append([
            miasto,
            kod_pocztowy,
            ulica,
            numer_domu
        ])

    headers = ["miasto", "kod_pocztowy", "ulica", "numer_domu"]

    writeToFile(headers, data, 'lokalizacja_narzedzia.csv')


def generate_data(num_records):
    data = []

    for _ in range(num_records):
        data.append([
            fake.day_of_month(),
            fake.month_name(),
            fake.date_between(start_date=datetime(year=2000, month=1, day=1), end_date=datetime.now()).year,
            fake.time()
        ])

    headers = ['dzien', 'miesiac', 'rok', 'godzina']

    writeToFile(headers, data, 'data.csv')


def generate_narzedzia_zbrodni(num_records):
    data = []

    for i in range(num_records):
        nazwa = [
            "Nóż z Ostrzem Stalowym", "Topór z Rękojeścią Drewnianą", "Żyleta z Uchwytem Plastikowym",
            "Sznur z Węzłem Zaciskowym",
            "Młot z Głowicą Metalową", "Łom z Końcówką Zakrzywioną", "Nożyczki z Ostrzami Długimi",
            "Siekiera z Trzonkiem Krótki",
            "Pistolet z Tłumikiem", "Strzelba z Lufą Skróconą", "Rewolwer z Bębnem Sześciostrzałowym",
            "Kij z Końcówką Tępą", "Pałka z Gumowym Wykończeniem", "Łańcuch z Ogniwami Stalowymi",
            "Lina z Pętlą Regulowaną",
            "Sztylet z Rękojeścią Skórzaną", "Brzytwa z Ostrzem Składanym", "Tasak z Krawędzią Ząbkowaną",
            "Wkrętak z Końcówką Ostrą", "Dłuto z Uchwytem Drewnianym", "Piła z Zębami Metalowymi",
            "Sekator z Mechanizmem Sprężynowym",
            "Kosa z Ostrzem Zakrzywionym", "Maczeta z Rękojeścią Gumową", "Bagnet z Mocowaniem Stalowym",
            "Igła z Końcówką Precyzyjną", "Strzykawka z Pojemnikiem Plastikowym", "Fiolka z Substancją Chemiczną",
            "Kabel z Izolacją Uszkodzoną", "Drut z Końcówką Zaostrzoną", "Szkło z Krawędzią Ostrą",
            "Butelka z Rozbitą Szyjką",
            "Klucz z Końcówką Tępą", "Śrubokręt z Rękojeścią Plastikową", "Młotek z Uchwytem Krótki",
            "Rura z Końcówką Metalową", "Latarka z Obudową Ciężką", "Kij z Gwoździami",
            "Deska z Wystającymi Gwoździami",
            "Nożyk z Ostrzem Wysuwanym", "Pilnik z Powierzchnią Szorstką", "Hak z Końcówką Zakrzywioną",
            "Łopatka z Krawędzią Ostrą", "Wiertło z Końcówką Spiralną", "Szydło z Uchwytem Drewnianym",
            "Szkielet z Krawędzią Tnącą",
            "Puszka z Krawędzią Ząbkowaną", "Kawałek Drewna z Gwoździem", "Rękawica z Wtopionymi Odłamkami",
            "Kij z Końcówką Zaostrą", "Pałka z Obciążnikiem", "Łańcuch z Zapięciem Ciężkim",
            "Lina z Włókien Syntetycznych",
            "Nóż z Ostrzem Ząbkowanym", "Topór z Głowicą Dwustronną", "Żyleta z Uchwytem Metalowym",
            "Sznur z Powłoką Woskowaną", "Młot z Końcówką Spiczastą", "Łom z Krawędzią Płaską",
            "Nożyczki z Końcówką Precyzyjną",
            "Siekiera z Rękojeścią Metalową", "Pistolet z Magazynkiem", "Strzelba z Kolbą Składaną",
            "Rewolwer z Lufą Krótka", "Kij z Uchwytem Gumowym", "Pałka z Linką", "Łańcuch z Końcówką Haka",
            "Lina z Węzłem Ślizgowym", "Sztylet z Ostrzem Dwustronnym", "Brzytwa z Rękojeścią Drewnianą",
            "Tasak z Uchwytem Ergonomicznym", "Wkrętak z Końcówką Płaską", "Dłuto z Krawędzią Szeroką",
            "Piła z Rękojeścią Plastikową",
            "Sekator z Ostrzem Krótki", "Kosa z Trzonkiem Drewnianym", "Maczeta z Krawędzią Prostą",
            "Bagnet z Rękojeścią Składaną", "Igła z Uchwytem Metalowym", "Strzykawka z Igłą Długą",
            "Fiolka z Płynem Bezbarwnym", "Kabel z Końcówką Odsłoniętą", "Drut z Powłoką Miedzianą",
            "Szkło z Odłamkami Ostrymi",
            "Butelka z Krawędzią Zbitą", "Klucz z Głowicą Ciężką", "Śrubokręt z Końcówką Krzyżową",
            "Młotek z Głowicą Płaską", "Rura z Powłoką Stalową", "Latarka z Końcówką Tępą", "Kij z Wtopionym Metalem",
            "Deska z Krawędzią Szorstką", "Nożyk z Mechanizmem Sprężynowym", "Pilnik z Końcówką Ostrą",
            "Hak z Uchwytem Stalowym", "Łopatka z Końcówką Płaską", "Wiertło z Rękojeścią",
            "Szydło z Końcówką Precyzyjną"
        ]

        data.append([
            i+1,
            i+1,
            random.choice(nazwa),
        ])

    headers = ['id_lokalizacji', 'id_daty', 'nazwa']

    writeToFile(headers, data, 'narzedzia_zbrodni.csv')

def generate_rodzaj_przestepstwa(num_records):
    data = []

    for i in range(num_records):
        opis = ""
        nazwa = random.choice([
                "Kradzież", "Morderstwo", "Oszuśtwo", "Włamanie",
                "Porwanie", "Terroryzm",
                "Napad", "Stalking"
            ])

        if nazwa == "Kradzież":
            opis = random.choice([
                "Kradzież z włamaniem", "Kradzież z użyciem przemocy",
                "Kradzież z włamaniem do mieszkania", "Kradzież z włamaniem do samochodu"
            ])
        elif nazwa == "Morderstwo":
            opis = random.choice([
                "Morderstwo z premedytacją", "Morderstwo w afekcie",
                "Morderstwo z użyciem broni palnej", "Morderstwo z użyciem narzędzia ostrego"
            ])
        elif nazwa  == "Oszuśtwo":
            opis = random.choice([
                "Oszuśtwo finansowe", "Oszuśtwo internetowe",
                "Oszuśtwo na szkodę firmy", "Oszuśtwo na szkodę osoby prywatnej"
            ])
        elif nazwa == "Włamanie":
            opis = random.choice([
                "Włamanie do mieszkania", "Włamanie do samochodu",
                "Włamanie do sklepu", "Włamanie do biura"
            ])
        elif nazwa == "Porwanie":
            opis = random.choice([
                "Porwanie dla okupu", "Porwanie z użyciem przemocy",
                "Porwanie dziecka", "Porwanie osoby dorosłej"
            ])
        elif nazwa ==  "Terroryzm":
            opis = random.choice([
                "Atak terrorystyczny", "Zamach bombowy",
                "Porwanie samolotu", "Porwanie autobusu"
            ])
        elif nazwa == "Napad":
            opis = random.choice([
                "Napad rabunkowy", "Napad z użyciem przemocy",
                "Napad na bank", "Napad na sklep"
            ])
        elif nazwa == "Stalking":
            opis = random.choice([
                "Stalking internetowy", "Stalking telefoniczny",
                "Stalking w miejscu pracy", "Stalking w szkole"
            ])

        data.append([
            i+1,
            random.randint(1, 100),
            nazwa,
            opis,
            random.choice(["Niska", "Średnia", "Wysoka"]),
        ])

        headers = ["id", 'id_narzedzia', 'nazwa', 'szczegolowy_opis', 'stopien_wykroczenia']

        writeToFile(headers, data, "rodzaj_przestepstwa.csv")


def generate_ofiary(num_records):
    data = []

    for _ in range(num_records):
        imie = fake.first_name()
        nazwisko = fake.last_name()
        data_urodzenia_str = fake.date_of_birth(minimum_age=18, maximum_age=80).strftime('%Y-%m-%d')
        data_urodzenia = datetime.strptime(data_urodzenia_str, '%Y-%m-%d')
        plec = random.choice(['M', 'K'])
        pesel = fake.pesel(sex=plec, date_of_birth=data_urodzenia)
        zwiazek_ze_sprawca = random.choice(["Tak", "Nie"])

        data.append([
            imie,
            nazwisko,
            data_urodzenia_str,
            plec,
            pesel,
            zwiazek_ze_sprawca
        ])

    headers = ['imie', 'nazwisko', 'data_urodzenia', 'plec', 'pesel', 'zwiazek_ze_sprawca']

    writeToFile(headers, data, "ofiary.csv")

def generate_tabela_faktow(num_records):
    data = []

    for i in range(num_records):
        id_czasu = random.randint(1, 5000)
        id_sprawcy = random.randint(1, 5000)
        id_ofiary = random.randint(1, 5000)
        id_rodzaju_przestepstwa = random.randint(1, 5000)
        id_statusu_sprawy = random.randint(1, 5000)
        id_motywu = random.randint(1, 5000)
        id_miejsca = random.randint(1, 8000)

        data.append([
            id_czasu,
            id_sprawcy,
            id_ofiary,
            id_rodzaju_przestepstwa,
            id_statusu_sprawy,
            id_motywu,
            id_miejsca
        ])

        headers = [
            "id_czasu",
            "id_sprawcy",
            "id_ofiary",
            "id_rodzaju_przestepstwa",
            "id_statusu_sprawcy",
            "id_motywu",
            "id_miejsca",
        ]

        writeToFile(headers, data, "tabela_faktow.csv")


def writeToFile(header, data, filename):
    if (not os.path.exists("result")):
        os.mkdir("./result")
    with open(f"result/{filename}", mode='w', encoding='utf-8', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(header)
        translated_data = [[replace_polish_characters(str(item)) for item in row] for row in data]
        writer.writerows(translated_data)

def replace_polish_characters(text):
    translation_map = {
        'ł': 'l', 'ń': 'n', 'ą': 'a', 'ę': 'e', 'ć': 'c', 'ź': 'z', 'ż': 'z', 'ó': 'o', 'ś': 's',
        'Ł': 'L', 'Ń': 'N', 'Ą': 'A', 'Ę': 'E', 'Ć': 'C', 'Ź': 'Z', 'Ż': 'Z', 'Ó': 'O', 'Ś': 'S'
    }
    translated_text = ''.join(translation_map.get(char, char) for char in text)
    return translated_text


if __name__ == "__main__":
    generate_dynamic_motives(5000)
    generate_status_sprawy_data(5000)
    generate_pora_dnia(5)
    generate_czas(5000)
    generate_adres_sprawcy(5000)
    generate_dane_osobowe(5000)
    generate_sprawcy(5000)
    generate_lokalizacja_narzedzia(100)
    generate_data(100)
    generate_narzedzia_zbrodni(100)
    generate_rodzaj_przestepstwa(5000)
    generate_ofiary(5000)
    generate_typy_lokalizacji(20)
    generate_adres_lokalizacji(8000)
    generate_lokalizacje(8000)
    generate_tabela_faktow(10000)