import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

import sqlite3, os, requests, xml.etree.ElementTree as ET, shutil
from datetime import datetime, timedelta
from collections import defaultdict

try:
    from config import *
except ImportError:
    print("HIBA: config.py hiányzik!")
    sys.exit(1)

DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "webshop_adatok.db")

# Kizart statusz ID-k (8-15 kozott: Elutasitva, Sikertelen, Visszafizetve, Visszakuldve, Torolt, Sikertelen bankkartyas)
KIZART_STATUSZOK = {8, 10, 11, 12, 14, 15}

def init_db():
    con = sqlite3.connect(DB_PATH)
    con.execute("DROP TABLE IF EXISTS napi_adatok")
    con.execute("""CREATE TABLE napi_adatok (
        datum TEXT NOT NULL,
        forras TEXT NOT NULL,
        osszeg REAL NOT NULL DEFAULT 0,
        PRIMARY KEY (datum, forras)
    )""")
    con.commit()
    return con

def save_day(con, datum, forras, osszeg):
    con.execute("INSERT OR REPLACE INTO napi_adatok (datum, forras, osszeg) VALUES (?, ?, ?)",
                (datum, forras, osszeg))
    con.commit()

def get_status_id_from_href(href):
    """Kiolvassa a statusz numerikus ID-t a href-bol"""
    import base64
    try:
        b64 = href.rstrip("/").split("/")[-1]
        decoded = base64.b64decode(b64 + "==").decode()
        return int(decoded.split("=")[-1])
    except:
        return None

def unas_login():
    payload = f"""<?xml version="1.0" encoding="UTF-8"?>
<Params><ApiKey>{UNAS_API_KEY}</ApiKey></Params>"""
    r = requests.post("https://api.unas.eu/shop/login",
                      data=payload.encode(),
                      headers={"Content-Type": "application/xml"}, timeout=30)
    token = ET.fromstring(r.text).findtext("Token")
    if not token:
        raise Exception(f"Login hiba: {r.text[:200]}")
    return token

def unas_find_total(token):
    """Megkeresi hány rendelés van összesen bináris kereséssel"""
    def check(start):
        p = f"""<?xml version="1.0" encoding="UTF-8"?>
<Params><StatusGroup>all</StatusGroup><LimitNum>1</LimitNum><LimitStart>{start}</LimitStart></Params>"""
        r = requests.post("https://api.unas.eu/shop/getOrder",
                          data=p.encode(),
                          headers={"Content-Type": "application/xml",
                                   "Authorization": f"Bearer {token}"},
                          timeout=30)
        return len(ET.fromstring(r.text).findall(".//Order")) > 0

    lo, hi = 10000, 100000
    while lo < hi - 50:
        mid = (lo + hi) // 2
        if check(mid):
            lo = mid
        else:
            hi = mid
    return lo

def unas_osszes(token, date_from, date_to):
    def get_page(start, num=500):
        p = f"""<?xml version="1.0" encoding="UTF-8"?>
<Params><StatusGroup>all</StatusGroup><LimitNum>{num}</LimitNum><LimitStart>{start}</LimitStart></Params>"""
        r = requests.post("https://api.unas.eu/shop/getOrder",
                          data=p.encode(),
                          headers={"Content-Type": "application/xml",
                                   "Authorization": f"Bearer {token}"},
                          timeout=120)
        return ET.fromstring(r.text).findall(".//Order")

    print(f"   Unas teljes rendelesszam keresese...")
    total = unas_find_total(token)
    print(f"   Becsult osszes rendeles: ~{total} db")

    daily = defaultdict(float)
    # Hátulról kezdjük, 500-asával
    start = total
    found_in_range = 0
    while start >= 0:
        orders = get_page(start, 500)
        if not orders:
            start -= 500
            continue

        page_dates = []
        for order in orders:
            raw_date = order.findtext("Date", "")[:10].replace(".", "-")
            try:
                datetime.strptime(raw_date, "%Y-%m-%d")
            except:
                continue
            page_dates.append(raw_date)
            if date_from <= raw_date <= date_to:
                statusz = (order.findtext("Status") or "").strip()
                if statusz == "Törölve":
                    continue
                osszeg = float(order.findtext("SumPriceGross", "0") or 0)
                daily[raw_date] += osszeg
                found_in_range += 1

        if page_dates:
            min_d = min(page_dates)
            max_d = max(page_dates)
            print(f"   Start={start}: {min_d} - {max_d}, {found_in_range} rendeles az idoszakban")
            if max_d < date_from:
                break

        start -= 500
        if start < 0:
            break

    return dict(daily)

def shoprenter_osszes(date_from, date_to):
    base_url = SHOPRENTER_API_URL.rstrip("/")
    auth = (SHOPRENTER_API_USER, SHOPRENTER_API_PASSWORD)
    daily = defaultdict(float)
    kizart_db = 0

    r = requests.get(f"{base_url}/orders", auth=auth,
                     headers={"Accept": "application/json"},
                     params={"page": 0, "limit": 25, "full": 1}, timeout=30)
    data = r.json()
    page_count = int(data.get("pageCount", 1) or 1)
    print(f"   Shoprenter osszes oldal: {page_count}")

    r_last = requests.get(f"{base_url}/orders", auth=auth,
                          headers={"Accept": "application/json"},
                          params={"page": page_count-1, "limit": 25, "full": 1}, timeout=30)
    last_items = r_last.json().get("items", [])
    if last_items:
        newest = last_items[-1]
        print(f"   Legujabb rendeles datuma: {newest.get('dateCreated', '?')[:10]}")

    import time

    total_found = 0
    for page in range(page_count - 1, -1, -1):
        # Retry logika: 3 kiserlet
        items = []
        for kiserletek in range(3):
            try:
                r = requests.get(f"{base_url}/orders", auth=auth,
                                 headers={"Accept": "application/json"},
                                 params={"page": page, "limit": 25, "full": 1}, timeout=60)
                if r.status_code == 200:
                    items = r.json().get("items", [])
                    break
                elif r.status_code == 429:
                    print(f"   [!!] Rate limit oldal {page}, var 10mp...")
                    time.sleep(10)
                else:
                    print(f"   [!!] HTTP hiba oldal {page}: {r.status_code} - {r.text[:100]}")
                    break
            except requests.exceptions.Timeout:
                print(f"   [!!] Timeout oldal {page}, {kiserletek+1}. kiserlet...")
                time.sleep(5)
            except Exception as e:
                print(f"   [!!] Hiba oldal {page}: {e}")
                break

        if not items:
            if kiserletek == 2:
                print(f"   [!!] 3 sikertelen kiserlet utan atlepjuk oldal {page}-t")
                continue  # atlepjuk, nem allunk meg
            break

        page_dates = [(o.get("dateCreated") or "")[:10] for o in items if o.get("dateCreated")]
        # Csak akkor allunk meg, ha az oldal OSSZES rendelese date_from elotti
        if page_dates and max(page_dates) < date_from:
            break

        for o in items:
            date_str = (o.get("dateCreated") or "")[:10]
            if not date_str or date_str < date_from or date_str > date_to:
                continue
            st = o.get("orderStatus")
            status_href = st.get("href", "") if isinstance(st, dict) else ""
            status_id = get_status_id_from_href(status_href)
            if status_id is None or status_id in KIZART_STATUSZOK:
                kizart_db += 1
                continue
            osszeg = float(o.get("total", 0) or 0)
            daily[date_str] += osszeg
            if osszeg > 0:
                total_found += 1

        if page % 50 == 0:
            min_d = min(page_dates) if page_dates else "?"
            print(f"   Oldal {page}, eddig {total_found} rendeles, {kizart_db} kizarva, legkorabbi: {min_d}")

    print(f"   Osszesen kizarva (torolt/sikertelen): {kizart_db} rendeles")
    return dict(daily)

def main():
    today = datetime.today()
    date_to = today.strftime("%Y-%m-%d")
    date_from = "2023-01-01"

    print(f"Visszamenoleges adattoltes: {date_from} - {date_to}")
    print(f"Kizart statuszok: Elutasitva(8), Sikertelen(10), Visszafizetve(11), Visszakuldve(12), Torolt(14), Sikertelen bankkartyas(15)")
    print()

    con = init_db()

    print(f"[1/2] Unas letoltes...")
    try:
        token = unas_login()
        unas_daily = unas_osszes(token, date_from, date_to)
        base = datetime.strptime(date_from, "%Y-%m-%d")
        days = (datetime.strptime(date_to, "%Y-%m-%d") - base).days + 1
        for i in range(days):
            d = (base + timedelta(days=i)).strftime("%Y-%m-%d")
            con.execute("INSERT OR REPLACE INTO napi_adatok (datum, forras, osszeg) VALUES (?, ?, ?)",
                        (d, "unas", unas_daily.get(d, 0)))
        con.commit()
        aktiv = sum(1 for v in unas_daily.values() if v > 0)
        print(f"   [OK] {aktiv} nap > 0, osszesen {sum(unas_daily.values()):,.0f} Ft")
    except Exception as e:
        print(f"   [!!] Hiba: {e}")
        import traceback; traceback.print_exc()

    print()
    print(f"[2/2] Shoprenter letoltes (hatulrol elore, kizarassal)...")
    try:
        shop_daily = shoprenter_osszes(date_from, date_to)
        base = datetime.strptime(date_from, "%Y-%m-%d")
        days = (datetime.strptime(date_to, "%Y-%m-%d") - base).days + 1
        for i in range(days):
            d = (base + timedelta(days=i)).strftime("%Y-%m-%d")
            con.execute("INSERT OR REPLACE INTO napi_adatok (datum, forras, osszeg) VALUES (?, ?, ?)",
                        (d, "shoprenter", shop_daily.get(d, 0)))
        con.commit()
        aktiv = sum(1 for v in shop_daily.values() if v > 0)
        print(f"   [OK] {aktiv} nap > 0, osszesen {sum(shop_daily.values()):,.0f} Ft")
    except Exception as e:
        print(f"   [!!] Hiba: {e}")
        import traceback; traceback.print_exc()

    con.close()

    # Excel masolata a fo mappaba is
    riport_mappa = os.path.join(os.path.dirname(os.path.abspath(__file__)), "riportok")
    fo_mappa = os.path.dirname(os.path.abspath(__file__))
    if os.path.exists(riport_mappa):
        xlsx_fajlok = sorted([f for f in os.listdir(riport_mappa) if f.endswith(".xlsx")])
        if xlsx_fajlok:
            legujabb = os.path.join(riport_mappa, xlsx_fajlok[-1])
            cel = os.path.join(fo_mappa, "webshop_riport_AKTUALIS.xlsx")
            try:
                shutil.copy2(legujabb, cel)
                print(f"   [OK] Masolat a fo mappaba: webshop_riport_AKTUALIS.xlsx")
            except Exception as e:
                print(f"   [!!] Masolas hiba: {e}")

    print()
    print("[OK] Kesz! Futtasd: python webshop_auto.py --teszt")

if __name__ == "__main__":
    main()
