#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import json
import time
from datetime import date, timedelta
from pathlib import Path
import requests
import pymysql

# =========================================
# CONFIG
# =========================================
ACCOUNTS_FILE = r"u:\PycharmProjects\FIO\accounts.json"
JSON_BASE_DIR = r"u:\Dropbox\!!!Days\Downloads Z230\Fio"

DB = {
    "host": "192.168.1.76",
    "port": 3307,
    "user": "root",
    "password": "Vlado9674+",
    "database": "fio",
    "charset": "utf8mb4",
}

BATCH_SIZE = 500


# =========================================
# HELPERS
# =========================================
def load_accounts(path: str):
    with open(path, "r", encoding="utf-8") as f:
        accounts = json.load(f)

    for acc in accounts:
        for key in ("name", "account_number", "token"):
            if key not in acc:
                raise ValueError(f"Missing key '{key}' in {acc}")

    return accounts


def fio_period_url(token: str, d_from: date, d_to: date):
    return f"https://fioapi.fio.cz/v1/rest/periods/{token}/{d_from:%Y-%m-%d}/{d_to:%Y-%m-%d}/transactions.json"


def fetch_fio_json(token: str, d_from: date, d_to: date):
    url = fio_period_url(token, d_from, d_to)
    resp = requests.get(url, timeout=30)
    if resp.status_code != 200:
        print(f"❌ HTTP {resp.status_code} from Fio: {url}")
        return None
    try:
        return resp.json()
    except json.JSONDecodeError:
        print("❌ JSON decode error")
        return None


def safe_col(t, n):
    key = f"column{n}"
    v = t.get(key)
    return None if not v else v.get("value")


def clean_date(dt):
    if not dt:
        return None
    return dt[:10]  # "YYYY-MM-DD"


def ensure_dir(p: Path):
    p.mkdir(parents=True, exist_ok=True)


def save_json(base_dir, account_cfg, data, d_from, d_to):
    folder = account_cfg["account_number"].replace("/", "_")
    out = Path(base_dir) / folder
    ensure_dir(out)

    filename = f"FULL_{d_from:%Y-%m-%d}_to_{d_to:%Y-%m-%d}.json"
    path = out / filename

    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

    return path


# =========================================
# MAIN
# =========================================
def main():
    print("\n=== FULL HISTORY IMPORT (Fio extra-permissions token) ===\n")

    accounts = load_accounts(ACCOUNTS_FILE)

    # show accounts to user
    for i, acc in enumerate(accounts, start=1):
        print(f"{i}. {acc['name']}  ({acc['account_number']})")

    print()
    while True:
        try:
            selection = int(input("Select account number (1..N): "))
            if 1 <= selection <= len(accounts):
                break
        except:
            pass
        print("Invalid selection, try again.\n")

    acc = accounts[selection - 1]
    name = acc["name"]
    token = acc["token"]
    acc_num = acc["account_number"]

    print(f"\nSelected: {name} ({acc_num})")
    print("⚠ Make sure you generated the special 10-minute FULL-HISTORY TOKEN.")
    input("Press ENTER to continue...")

    # full 20-year history
    today = date.today()
    d_from = today.replace(year=today.year - 20)
    d_to = today

    print(f"\nDownloading ALL transactions from {d_from} to {d_to}…")

    start_time = time.time()

    data = fetch_fio_json(token, d_from, d_to)
    if data is None:
        print("❌ Download failed")
        return

    # save JSON
    json_path = save_json(JSON_BASE_DIR, acc, data, d_from, d_to)
    print(f"JSON saved to {json_path}")

    # extract transactions
    tlist = data["accountStatement"]["transactionList"].get("transaction", [])
    if isinstance(tlist, dict):
        tlist = [tlist]

    print(f"Transactions loaded: {len(tlist)}")

    if not tlist:
        print("No transactions found, exiting.")
        return

    # MySQL
    conn = pymysql.connect(**DB)
    cur = conn.cursor()

    sql = """
    INSERT INTO transactions
    (
        datum, objem, mena, cislo_uctu, protiucet, kod_banky,
        ks, vs, ss, zprava_pro_prijemce, poznamka,
        id_operace, id_pokynu, ks_1, nazev_banky, nazev_protiuctu,
        ss_1, typ, upresneni_objem, upresneni_mena, vs_1, zadal
    )
    VALUES
    (
        %(datum)s, %(objem)s, %(mena)s, %(cislo_uctu)s, %(protiucet)s, %(kod_banky)s,
        %(ks)s, %(vs)s, %(ss)s, %(zprava)s, %(poznamka)s,
        %(id_operace)s, %(id_pokynu)s, %(ks1)s, %(nazev_banky)s, %(nazev_protiuctu)s,
        %(ss1)s, %(typ)s, %(upr_objem)s, %(upr_mena)s, %(vs1)s, %(zadal)s
    )
    ON DUPLICATE KEY UPDATE
        datum=VALUES(datum),
        objem=VALUES(objem),
        mena=VALUES(mena),
        protiucet=VALUES(protiucet),
        kod_banky=VALUES(kod_banky),
        ks=VALUES(ks),
        vs=VALUES(vs),
        ss=VALUES(ss),
        zprava_pro_prijemce=VALUES(zprava_pro_prijemce),
        poznamka=VALUES(poznamka),
        ks_1=VALUES(ks_1),
        nazev_banky=VALUES(nazev_banky),
        nazev_protiuctu=VALUES(nazev_protiuctu),
        ss_1=VALUES(ss_1),
        typ=VALUES(typ),
        upresneni_objem=VALUES(upresneni_objem),
        upresneni_mena=VALUES(upresneni_mena),
        vs_1=VALUES(vs_1),
        zadal=VALUES(zadal)
    """

    fio_acc_id = data["accountStatement"]["info"]["accountId"]

    # build batch
    rows = []
    for t in tlist:
        rows.append({
            "datum": clean_date(safe_col(t, 0)),
            "objem": safe_col(t, 1),
            "mena": safe_col(t, 14),
            "cislo_uctu": fio_acc_id,
            "protiucet": safe_col(t, 2),
            "kod_banky": safe_col(t, 3),
            "ks": safe_col(t, 4),
            "vs": safe_col(t, 5),
            "ss": safe_col(t, 6),
            "zprava": safe_col(t, 16),
            "poznamka": safe_col(t, 25),
            "id_operace": safe_col(t, 22),
            "id_pokynu": safe_col(t, 24),
            "ks1": safe_col(t, 18),
            "nazev_banky": safe_col(t, 15),
            "nazev_protiuctu": safe_col(t, 10),
            "ss1": safe_col(t, 19),
            "typ": safe_col(t, 8),
            "upr_objem": safe_col(t, 20),
            "upr_mena": safe_col(t, 21),
            "vs1": safe_col(t, 17),
            "zadal": safe_col(t, 12),
        })

    # batch insert
    inserted = 0
    for i in range(0, len(rows), BATCH_SIZE):
        chunk = rows[i:i + BATCH_SIZE]
        cur.executemany(sql, chunk)
        conn.commit()
        inserted += len(chunk)

    cur.close()
    conn.close()

    print(f"\n✓ Inserted/updated {inserted} transactions.")
    print(f"Total time: {time.time() - start_time:.2f} s")


if __name__ == "__main__":
    main()
