# -*- coding: utf-8 -*-
"""Symulator kas sklepów Nordvella: wysyła transakcje do Eventstream w Microsoft Fabric.

Przed uruchomieniem:
  pip install azure-eventhub
  Parametry połączenia skopiuj w Eventstream: źródło (niestandardowy punkt końcowy) > Szczegóły >
  Centrum zdarzeń > Uwierzytelnianie klucza SAS > Parametry połączenia - klucz podstawowy.

  Linux/macOS:  export FABRIC_ES_CONN="Endpoint=sb://...;EntityPath=..."
  PowerShell:   $env:FABRIC_ES_CONN = "Endpoint=sb://...;EntityPath=..."

Uruchomienie:  python wyslij_transakcje.py --minutes 15 --per-second 3
Pliki sklepy.csv i produkty.csv muszą leżeć w tym samym katalogu (są w paczce danych do przewodnika).
Mniej więcej w połowie przebiegu sklep Warszawa Centrum dostaje kilka minut większego ruchu,
żeby było na czym przetestować alert w Aktywatorze.
"""
import argparse
import csv
import json
import os
import random
import time
from datetime import datetime, timezone

from azure.eventhub import EventData, EventHubProducerClient

HERE = os.path.dirname(os.path.abspath(__file__))


def read_csv(name):
    with open(os.path.join(HERE, name), encoding="utf-8") as f:
        return list(csv.DictReader(f))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--minutes", type=float, default=15)
    parser.add_argument("--per-second", type=float, default=3)
    parser.add_argument("--connection", default=os.environ.get("FABRIC_ES_CONN", ""))
    args = parser.parse_args()
    if not args.connection:
        raise SystemExit("Brak parametrów połączenia: ustaw zmienną FABRIC_ES_CONN albo podaj --connection")

    stores = read_csv("sklepy.csv")
    products = [p for p in read_csv("produkty.csv") if not p.get("AktywnyDo")]
    # sklepy typu Flagship sprzedają mniej więcej trzy razy więcej niż pozostałe
    store_weights = [3 if s["Typ"] == "Flagship" else 1 for s in stores]
    producer = EventHubProducerClient.from_connection_string(args.connection)
    start, sent = time.time(), 0
    end = start + args.minutes * 60
    with producer:
        while time.time() < end:
            progress = (time.time() - start) / (args.minutes * 60)
            peak = 0.45 < progress < 0.65  # kilka minut dużego ruchu w jednym sklepie
            batch = producer.create_batch()
            for _ in range(max(1, int(args.per_second))):
                store = stores[0] if peak and random.random() < 0.6 else random.choices(stores, weights=store_weights)[0]
                product = random.choice(products)
                qty = random.choices([1, 2, 3], weights=[7, 2, 1])[0]
                event = {
                    "Czas": datetime.now(timezone.utc).isoformat(timespec="milliseconds"),
                    "SklepID": int(store["SklepID"]),
                    "Miasto": store["Miasto"],
                    "Region": store["Region"],
                    "Kanal": "Online" if store["Region"] == "Online" else "Stacjonarne",
                    "Produkt": product["Nazwa"],
                    "Kategoria": product["Kategoria"],
                    "Ilosc": qty,
                    "WartoscBrutto": round(float(product["CenaBrutto"]) * qty, 2),
                    "FormaPlatnosci": random.choices(["Karta", "BLIK", "Gotówka", "Raty"], weights=[5, 3, 2, 1])[0],
                }
                batch.add(EventData(json.dumps(event, ensure_ascii=False)))
                sent += 1
            producer.send_batch(batch)
            time.sleep(1)
            if sent % 300 < args.per_second:
                print(f"{datetime.now():%H:%M:%S} wysłano {sent} transakcji")
    print("Koniec, wysłano", sent, "transakcji")


if __name__ == "__main__":
    main()
