"""
Etude KontoRanking : ile naprawde kosztuje "darmowe" konto? (stan 22.10.2026)
Coût annuel réel de 7 comptes personnels selon 4 profils d'usage.
Sources : products.js (audit 08.10.2026), cennik Millennium 360° (umowy od 30.09.2026),
ING Go : Tabela Opłat i Prowizji ING dla osób fizycznych, tekst jednolity 10.08.2026
(vérifiée le 22.10.2026, concordante avec la page produit ing.pl).

Hypothèses communes :
- "obcy bankomat" = distributeur hors réseau de la banque (type Euronet).
- Le client rationnel choisit la méthode de retrait la moins chère (carte ou BLIK).
  BLIK chez Euronet limité à 200 zł par retrait : au-delà, BLIK impossible (on garde la carte).
- Etat stable (hors promotions de bienvenue, hors mois de grâce).
- Frais du titulaire uniquement ; frais éventuels de l'opérateur du distributeur non comptés.
"""
import csv, json, os

PROFILES = {
    "student": dict(label="Student (21 lat)", age=21, n_pay=8, sum_pay=400, withdrawals=[100, 100]),
    "oszczedny": dict(label="Oszczędny dorosły (35 lat)", age=35, n_pay=3, sum_pay=200, withdrawals=[200]),
    "aktywny": dict(label="Aktywny dorosły (35 lat)", age=35, n_pay=20, sum_pay=1500, withdrawals=[400, 400]),
    "gotowka": dict(label="Lubi gotówkę (45 lat)", age=45, n_pay=4, sum_pay=250, withdrawals=[150, 150, 150, 150]),
}

def mbank(p):
    card = 0 if p["sum_pay"] >= 350 else 9
    atm = sum(0 if a >= 300 else 2.5 for a in p["withdrawals"])
    return 0, card, atm

def ing(p):
    # TOiP ING pour particuliers, texte consolidé au 10.08.2026, Konto w Planie ING Go :
    # - carte, distributeur hors ING / Planet Cash (pkt 4c, note 7) : < 26 ans, 1er retrait
    #   du mois 0 zł puis 2,50 zł ; >= 26 ans, 10 zł par retrait ;
    # - BLIK, même distributeur (pkt 5, note 3) : < 26 ans, 0 zł ; >= 26 ans, 1er retrait
    #   du mois 0 zł puis 5 zł.
    # BLIK coûte toujours moins cher que la carte : le client rationnel l'utilise jusqu'à
    # 200 zł (limite Euronet), la carte au-delà. Compteurs de « 1er retrait » séparés.
    young = p["age"] < 26
    card = 0 if (young or p["sum_pay"] >= 300) else 10
    atm = 0
    n_blik = n_card = 0
    for a in p["withdrawals"]:
        if a <= 200:
            atm += 0 if (young or n_blik == 0) else 5
            n_blik += 1
        else:
            atm += (0 if n_card == 0 else 2.5) if young else 10
            n_card += 1
    return 0, card, atm

def bnp(p):
    young = p["age"] < 26
    card = 0 if young else (2 if p["n_pay"] >= 3 else 9)
    atm = 0
    for a in p["withdrawals"]:
        if young:
            continue
        atm += 5 if a <= 200 else 10   # BLIK 5 zł (<=200 zł), sinon carte 10 zł
    return 0, card, atm

def pko(p):
    card = 0 if p["n_pay"] >= 5 else 10
    atm = sum(0 if a <= 200 else 10 for a in p["withdrawals"])  # BLIK gratuit (<=200), carte 10 zł
    return 0, card, atm

def millennium(p):
    young = 18 <= p["age"] <= 26
    ok = p["n_pay"] >= (1 if young else 5)
    card = 0 if ok else (5 if young else 11)
    atm = 0 if ok else 5 * len(p["withdrawals"])
    return 0, card, atm

def pekao(p):
    return 0, 0, 0  # commission Pekao 0 zł ; frais opérateur éventuels non comptés

def erste(p):
    ok = p["sum_pay"] >= 300
    acc = 0 if ok else 6
    card = 0 if ok else 9
    atm = sum(0 if a <= 200 else 3 for a in p["withdrawals"])  # BLIK gratuit, carte 3 zł
    return acc, card, atm

BANKS = [
    ("mBank", "eKonto do usług", mbank),
    ("ING Bank Śląski", "Konto w Planie ING Go", ing),
    ("BNP Paribas", "Konto Otwarte na Ciebie", bnp),
    ("PKO Bank Polski", "Konto za Zero", pko),
    ("Bank Millennium", "Konto Millennium 360°", millennium),
    ("Bank Pekao", "Konto Przekorzystne", pekao),
    ("Erste Bank Polska", "Konto Smart", erste),
]

def main():
    rows = []
    for pid, p in PROFILES.items():
        for bank, product, fn in BANKS:
            acc, card, atm = fn(p)
            monthly = acc + card + atm
            rows.append(dict(profil=pid, profil_label=p["label"], bank=bank, konto=product,
                             konto_mies=acc, karta_mies=card, bankomaty_mies=atm,
                             razem_mies=round(monthly, 2), razem_rok=round(monthly * 12, 2)))
    out = os.path.dirname(os.path.abspath(__file__))
    with open(os.path.join(out, "wyniki.csv"), "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=list(rows[0].keys())); w.writeheader(); w.writerows(rows)
    with open(os.path.join(out, "wyniki.json"), "w", encoding="utf-8") as f:
        json.dump(dict(profiles=PROFILES, rows=rows), f, ensure_ascii=False, indent=1)
    for pid, p in PROFILES.items():
        print(f"\n== {p['label']} ==")
        for r in sorted([r for r in rows if r["profil"] == pid], key=lambda r: r["razem_rok"]):
            print(f"  {r['bank']:<20} {r['razem_rok']:>7.2f} zł/rok  (konto {r['konto_mies']}, karta {r['karta_mies']}, bankomaty {r['bankomaty_mies']} /mies.)")

if __name__ == "__main__":
    main()
