import json
import os
from typing import Optional
from config import PRODUCTS_FILE, USERS_FILE, ORDERS_FILE, SETTINGS_FILE


def load_json(path):
    if not os.path.exists(path):
        return {}
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def save_json(path, data):
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def get_products():
    return load_json(PRODUCTS_FILE)


def save_products(data):
    save_json(PRODUCTS_FILE, data)


def get_users():
    return load_json(USERS_FILE)


def save_users(data):
    save_json(USERS_FILE, data)


def get_orders():
    data = load_json(ORDERS_FILE)
    if isinstance(data, dict):
        return []
    return data


def save_orders(data):
    save_json(ORDERS_FILE, data)


def get_settings():
    return load_json(SETTINGS_FILE)


def save_settings(data):
    save_json(SETTINGS_FILE, data)


def get_user(user_id: int) -> dict:
    users = get_users()
    uid = str(user_id)
    if uid not in users:
        users[uid] = {"balance": 0, "username": "", "name": ""}
        save_users(users)
    return users[uid]


def update_user(user_id: int, data: dict):
    users = get_users()
    uid = str(user_id)
    if uid not in users:
        users[uid] = {"balance": 0, "username": "", "name": ""}
    users[uid].update(data)
    save_users(users)


def add_balance(user_id: int, amount: int):
    user = get_user(user_id)
    new_balance = user.get("balance", 0) + amount
    update_user(user_id, {"balance": new_balance})
    return new_balance


def deduct_balance(user_id: int, amount: int) -> bool:
    user = get_user(user_id)
    if user.get("balance", 0) < amount:
        return False
    new_balance = user["balance"] - amount
    update_user(user_id, {"balance": new_balance})
    return True


def get_category_by_id(cat_id: str):
    data = get_products()
    for cat in data.get("categories", []):
        if cat["id"] == cat_id:
            return cat
    return None


def get_product_by_id(prod_id: str):
    data = get_products()
    for prod in data.get("products", []):
        if prod["id"] == prod_id:
            return prod
    return None


def get_products_by_category(cat_id: str):
    data = get_products()
    return [p for p in data.get("products", []) if p["category_id"] == cat_id and p.get("active", True)]


def pop_stock(prod_id: str) -> Optional[str]:
    data = get_products()
    for prod in data["products"]:
        if prod["id"] == prod_id:
            if prod["stock"]:
                item = prod["stock"].pop(0)
                save_products(data)
                return item
    return None


def add_order(order: dict):
    orders = get_orders()
    orders.append(order)
    save_orders(orders)


def get_order_by_id(order_id: str):
    orders = get_orders()
    for o in orders:
        if o.get("order_id") == order_id:
            return o
    return None


def update_order(order_id: str, data: dict):
    orders = get_orders()
    for o in orders:
        if o.get("order_id") == order_id:
            o.update(data)
    save_orders(orders)