"""
Backend UBS Lifestyle Clone - Telegram Webhook Mode
====================================================

Dioptimasi untuk shared hosting cPanel (Phusion Passenger / Python App).
Telegram menggunakan WEBHOOK (bukan long polling) sehingga tidak butuh
background thread — cocok untuk shared hosting.

Setup setelah deploy:
    python scripts/setup_webhook.py
"""
import json
import os
import threading
import time
import uuid
from datetime import datetime
from pathlib import Path

import requests
from flask import Flask, jsonify, request, send_from_directory
from flask_cors import CORS

try:
    from dotenv import load_dotenv
    load_dotenv(Path(__file__).parent / ".env")
except ImportError:
    pass

# ===== CONFIG =====
BOT_TOKEN    = os.getenv("TELEGRAM_BOT_TOKEN", "").strip()
ADMIN_CHAT_ID = os.getenv("TELEGRAM_ADMIN_CHAT_ID", "").strip()
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "admin123").strip()
PORT = int(os.getenv("PORT", "5000"))
# URL publik domain cPanel — dipakai untuk daftarkan webhook ke Telegram
WEBHOOK_DOMAIN = os.getenv("WEBHOOK_DOMAIN", "https://ubsgoldlifestyle.com").rstrip("/")

ROOT = Path(__file__).resolve().parent.parent
ORDERS_FILE       = Path(__file__).resolve().parent / "orders.json"
TESTIMONIALS_FILE = Path(__file__).resolve().parent / "testimonials.json"
BANKS_FILE        = Path(__file__).resolve().parent / "bank_accounts.json"
QRIS_DIR          = Path(__file__).resolve().parent / "qris_images"
QRIS_DIR.mkdir(exist_ok=True)

TG_API  = f"https://api.telegram.org/bot{BOT_TOKEN}"
TG_FILE = f"https://api.telegram.org/file/bot{BOT_TOKEN}"

# ===== ORDERS =====
_orders_lock = threading.Lock()

def load_orders():
    if ORDERS_FILE.exists():
        try:
            return json.loads(ORDERS_FILE.read_text(encoding="utf-8"))
        except Exception:
            return {}
    return {}

def save_orders(data):
    ORDERS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")

orders = load_orders()

# ===== TESTIMONIALS =====
_testi_lock = threading.Lock()

SEED_TESTIMONIALS = [
    {"id":"T1","name":"Sari Wijaya","initial":"S","rating":5,"createdAt":"2026-05-15T10:00:00","title":"Kualitas premium, pelayanan ramah","message":"Beli kalung emas 8K dari UBS, hasilnya jauh dari ekspektasi. Kemasannya elegan, sertifikat lengkap, dan adminnya responsif banget di Telegram. Recommended!","product":"Kalung Emas 8K","verified":True},
    {"id":"T2","name":"Budi Santoso","initial":"B","rating":5,"createdAt":"2026-05-22T14:30:00","title":"Cocok buat investasi","message":"Sudah beberapa kali beli logam mulia di sini untuk koleksi. Harga kompetitif, gampang banget proses checkout-nya. QRIS langsung muncul, gak ribet.","product":"Logam Mulia 5 Gram Classic","verified":True},
    {"id":"T3","name":"Dian Permata","initial":"D","rating":4,"createdAt":"2026-05-28T09:15:00","title":"Hadiah ulang tahun istri","message":"Beli cincin Kiara Collection untuk hadiah anniv. Istri suka banget desainnya. Pengirimannya cepat lewat J&T, nyampe dalam 2 hari ke Bandung.","product":"Cincin Emas Kiara 8K","verified":True},
    {"id":"T4","name":"Lia Hartono","initial":"L","rating":5,"createdAt":"2026-06-01T16:45:00","title":"Koleksi Disney lucu banget","message":"Anak saya seneng banget dapet gelang Disney Mickey Mouse. Kualitas emasnya bagus dan kemasannya cute. Pasti akan repeat order!","product":"Gelang Emas Anak Disney 17K","verified":True},
    {"id":"T5","name":"Rendy Pratama","initial":"R","rating":5,"createdAt":"2026-06-04T11:20:00","title":"Lebih murah dari toko offline","message":"Dibanding toko emas konvensional, harga di UBS Lifestyle lebih kompetitif untuk kualitas yang sama. Plus dapet sertifikat resmi.","product":"Anting Emas Sparkle","verified":True},
    {"id":"T6","name":"Maya Anggraini","initial":"M","rating":5,"createdAt":"2026-06-05T08:30:00","title":"Liontin Sanrio bikin nostalgia","message":"Akhirnya kebeli liontin Hello Kitty edisi spesial. Detailnya rapih banget, dan ukurannya pas untuk dipakai sehari-hari. Suka banget!","product":"Liontin Sanrio Hello Kitty","verified":True},
    {"id":"T7","name":"Andi Setiawan","initial":"A","rating":4,"createdAt":"2026-06-05T13:10:00","title":"Pengiriman cepat ke Surabaya","message":"Pesan sore, sampai 2 hari kemudian. JNE YES emang juara. Sayang stok cincin yang saya mau habis, jadi pilih variant lain.","product":"Cincin Polos 8K","verified":True},
    {"id":"T8","name":"Putri Ramadhani","initial":"P","rating":5,"createdAt":"2026-06-06T07:45:00","title":"Cocok untuk hadiah lebaran","message":"Beli logam mulia 2 gram buat hadiah ke ortu. Kemasannya rapi, ada kartu ucapannya. Ortu seneng banget!","product":"Logam Mulia 2 Gram Classic","verified":True},
    {"id":"T9","name":"Hendra Kusuma","initial":"H","rating":5,"createdAt":"2026-06-06T19:20:00","title":"Pertama kali beli online, lancar","message":"Awalnya ragu beli emas online, tapi prosesnya jelas dan aman. CS-nya jelasin step-by-step. Barangnya bagus banget.","product":"Gelang Emas 8K","verified":True},
    {"id":"T10","name":"Nurul Aisyah","initial":"N","rating":4,"createdAt":"2026-06-07T10:00:00","title":"Desainnya minimalis dan modern","message":"Saya suka koleksi Korean Style-nya. Modelnya simpel tapi elegan, cocok dipake ke kantor.","product":"Anting Korean Style","verified":True},
]

def load_testimonials():
    if TESTIMONIALS_FILE.exists():
        try:
            return json.loads(TESTIMONIALS_FILE.read_text(encoding="utf-8"))
        except Exception:
            return list(SEED_TESTIMONIALS)
    return list(SEED_TESTIMONIALS)

def save_testimonials(data):
    TESTIMONIALS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")

testimonials = load_testimonials()
if not TESTIMONIALS_FILE.exists():
    save_testimonials(testimonials)

# ===== BANK ACCOUNTS =====
_banks_lock = threading.Lock()

SUPPORTED_BANKS = [
    {"code":"bca","name":"BCA"},{"code":"mandiri","name":"Mandiri"},
    {"code":"bni","name":"BNI"},{"code":"bri","name":"BRI"},
    {"code":"cimb","name":"CIMB Niaga"},{"code":"permata","name":"Permata"},
    {"code":"danamon","name":"Danamon"},{"code":"bsi","name":"BSI"},
    {"code":"btn","name":"BTN"},{"code":"ocbc","name":"OCBC NISP"},
    {"code":"maybank","name":"Maybank"},{"code":"panin","name":"Panin"},
    {"code":"mega","name":"Mega"},{"code":"bjb","name":"BJB"},
    {"code":"hsbc","name":"HSBC"},{"code":"uob","name":"UOB"},
    {"code":"sinarmas","name":"Sinar Mas"},{"code":"muamalat","name":"Muamalat"},
]

def load_banks():
    if BANKS_FILE.exists():
        try:
            return json.loads(BANKS_FILE.read_text(encoding="utf-8"))
        except Exception:
            return []
    return [
        {"id":"bca","bank":"BCA","logo":"assets/banks/bca.png","accountNumber":"1234567890","accountHolder":"PT UBS Lifestyle","active":True},
        {"id":"mandiri","bank":"Mandiri","logo":"assets/banks/mandiri.png","accountNumber":"1450098765432","accountHolder":"PT UBS Lifestyle","active":True},
    ]

def save_banks(data):
    BANKS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")

bank_accounts = load_banks()
if not BANKS_FILE.exists():
    save_banks(bank_accounts)

# ===== HELPERS =====

def check_admin(req):
    return req.headers.get("X-Admin-Password", "") == ADMIN_PASSWORD


def tg_send(chat_id, text, reply_markup=None, parse_mode="HTML"):
    """Kirim pesan teks ke Telegram."""
    if not BOT_TOKEN:
        return None
    payload = {"chat_id": chat_id, "text": text, "parse_mode": parse_mode}
    if reply_markup:
        payload["reply_markup"] = json.dumps(reply_markup)
    try:
        return requests.post(f"{TG_API}/sendMessage", data=payload, timeout=10).json()
    except Exception as e:
        print(f"[ERR] tg_send: {e}")
        return None


def tg_send_photo(chat_id, photo_bytes, filename, caption=None, reply_markup=None):
    """Kirim foto (bytes) ke Telegram."""
    if not BOT_TOKEN:
        return None
    data = {"chat_id": chat_id, "parse_mode": "HTML"}
    if caption:
        data["caption"] = caption
    if reply_markup:
        data["reply_markup"] = json.dumps(reply_markup)
    try:
        return requests.post(f"{TG_API}/sendPhoto", data=data,
                             files={"photo": (filename, photo_bytes)}, timeout=20).json()
    except Exception as e:
        print(f"[ERR] tg_send_photo: {e}")
        return None


def tg_download_photo(file_id, save_path):
    """Download foto dari Telegram by file_id."""
    try:
        info = requests.get(f"{TG_API}/getFile", params={"file_id": file_id}, timeout=10).json()
        if not info.get("ok"):
            return False
        img = requests.get(f"{TG_FILE}/{info['result']['file_path']}", timeout=15)
        if img.status_code == 200:
            save_path.write_bytes(img.content)
            return True
    except Exception as e:
        print(f"[ERR] tg_download: {e}")
    return False


def format_order_notification(order):
    items_lines = [f"  • {it['name'][:40]} ×{it['qty']} - Rp {it['price']*it['qty']:,}"
                   for it in order["items"]]
    ship = order.get("shippingMethod", {})
    cust = order["customer"]
    payment = order.get("payment", "qris")
    bank = order.get("paymentBank")

    if payment == "bank-transfer" and bank:
        payment_info = (f"💳 <b>Transfer Bank</b>\n"
                        f"🏦 {bank['name']} - <code>{bank.get('accountNumber','-')}</code>\n"
                        f"👤 a.n. {bank.get('accountHolder','-')}")
        footer = "<i>📌 Tunggu konfirmasi pembayaran, lalu klik tombol Konfirmasi.</i>"
    else:
        payment_info = "💳 <b>QRIS</b>"
        footer = "<i>📌 BALAS pesan ini dengan FOTO QRIS untuk customer.</i>"

    return (
        f"🛒 <b>ORDER BARU</b>\n<code>{order['id']}</code>\n\n"
        f"👤 <b>{cust['name']}</b>\n📱 {cust['phone']}\n📧 {cust['email']}\n\n"
        f"📍 <b>Alamat:</b>\n{cust['address']}\n{cust['city']}, {cust['province']} {cust['zip']}\n\n"
        f"📦 <b>Items ({len(order['items'])}):</b>\n" + "\n".join(items_lines) +
        f"\n\n🚚 Kurir: <b>{ship.get('label','-')}</b>\n{payment_info}\n"
        f"💰 Subtotal: Rp {order['subtotal']:,}\n"
        f"🚛 Ongkir: Rp {order['shipping']:,}\n"
        f"💵 <b>TOTAL: Rp {order['total']:,}</b>\n\n{footer}"
    )

# ===== FLASK APP =====

app = Flask(__name__, static_folder=str(ROOT), static_url_path="")
CORS(app, resources={r"/api/*": {"origins": "*"}})


@app.route("/")
def root():
    return send_from_directory(str(ROOT), "index.html")


@app.route("/api/health")
def health():
    return jsonify({"ok": True, "bot_configured": bool(BOT_TOKEN and ADMIN_CHAT_ID),
                    "orders_count": len(orders), "mode": "webhook"})


@app.route("/api/config")
def api_config():
    return jsonify({"ok": True, "version": "1.0",
                    "bot_configured": bool(BOT_TOKEN and ADMIN_CHAT_ID)})


@app.route("/api/ping")
def api_ping():
    return jsonify({"pong": True})


# ===== TELEGRAM WEBHOOK =====

@app.route(f"/webhook/telegram", methods=["POST"])
def telegram_webhook():
    """Telegram push update ke endpoint ini setiap ada pesan/callback."""
    update = request.get_json(silent=True)
    if not update:
        return "ok"
    try:
        handle_update(update)
    except Exception as e:
        print(f"[ERR] webhook handle: {e}")
    return "ok"


@app.route("/api/webhook/set", methods=["POST"])
def set_webhook():
    """Endpoint untuk register webhook URL ke Telegram (dipanggil sekali saat setup)."""
    if not check_admin(request):
        return jsonify({"error": "Unauthorized"}), 401
    if not BOT_TOKEN:
        return jsonify({"error": "BOT_TOKEN belum di-set"}), 400
    webhook_url = f"{WEBHOOK_DOMAIN}/webhook/telegram"
    r = requests.post(f"{TG_API}/setWebhook",
                      json={"url": webhook_url, "allowed_updates": ["message", "callback_query"]},
                      timeout=10).json()
    return jsonify(r)


@app.route("/api/webhook/info", methods=["GET"])
def webhook_info():
    """Cek status webhook yang terdaftar di Telegram."""
    if not BOT_TOKEN:
        return jsonify({"error": "BOT_TOKEN belum di-set"}), 400
    r = requests.get(f"{TG_API}/getWebhookInfo", timeout=10).json()
    return jsonify(r)

def handle_update(update):
    """Proses update dari Telegram (sama persis dengan logika polling lama)."""

    # ── Foto (QRIS atau bukti transfer) ──────────────────────────────────────
    if "message" in update and "photo" in update["message"]:
        msg = update["message"]
        reply_to = msg.get("reply_to_message")
        target = None

        if reply_to:
            reply_msg_id = reply_to["message_id"]
            with _orders_lock:
                matches = [o for o in orders.values()
                           if o.get("telegramMessageId") == reply_msg_id]
                if matches:
                    waiting = [o for o in matches if o.get("status") == "waiting_qris"]
                    target = waiting[0] if waiting else matches[0]

        if not target:
            with _orders_lock:
                wq = [o for o in orders.values() if o.get("status") == "waiting_qris"]
                if wq:
                    target = sorted(wq, key=lambda o: o.get("createdAt",""), reverse=True)[0]

        if not target:
            tg_send(msg["chat"]["id"],
                    "⚠️ Tidak ada order yang menunggu QRIS saat ini.")
            return

        photo = msg["photo"][-1]
        filename = f"{target['id']}.jpg"
        if tg_download_photo(photo["file_id"], QRIS_DIR / filename):
            with _orders_lock:
                target["qrisUrl"] = f"/qris/{filename}"
                target["status"] = "qris_ready"
                save_orders(orders)
            tg_send(msg["chat"]["id"],
                    f"✅ QRIS untuk <code>{target['id']}</code> berhasil dikirim ke customer.")
        else:
            tg_send(msg["chat"]["id"], "❌ Gagal download foto.")

    # ── Pesan teks ────────────────────────────────────────────────────────────
    elif "message" in update:
        msg = update["message"]
        text = msg.get("text", "")
        if text in ["/start", "/help"]:
            tg_send(msg["chat"]["id"],
                    "👋 <b>UBS Lifestyle Bot</b>\n\n"
                    "Bot ini kirim notifikasi setiap ada order baru.\n"
                    "<b>Cara handle order:</b>\n"
                    "1. Tunggu pesan 🛒\n"
                    "2. <b>REPLY</b> pesan itu dengan foto QRIS\n"
                    "3. Web customer auto-update\n"
                    "4. Saat customer klik 'Saya sudah bayar', kamu dapat tombol konfirmasi")

    # ── Callback button ───────────────────────────────────────────────────────
    elif "callback_query" in update:
        cq = update["callback_query"]
        data_str = cq.get("data", "")
        chat_id = cq["message"]["chat"]["id"]
        cb_id = cq["id"]

        if ":" not in data_str:
            return
        action, oid = data_str.split(":", 1)

        with _orders_lock:
            order = orders.get(oid)
            if not order:
                requests.post(f"{TG_API}/answerCallbackQuery",
                              data={"callback_query_id": cb_id, "text": "Order tidak ditemukan"})
                return
            if action == "cancel":
                order["status"] = "cancelled"
                msg_text = f"❌ Order <code>{oid}</code> dibatalkan."
            elif action == "confirm":
                order["status"] = "paid"
                order["paidAt"] = datetime.now().isoformat()
                msg_text = f"✅ Pembayaran <code>{oid}</code> dikonfirmasi. Pesanan diproses."
            elif action == "reject":
                order["status"] = "qris_ready"
                msg_text = f"⚠️ Pembayaran <code>{oid}</code> ditolak. Customer harus bayar ulang."
            else:
                msg_text = "Unknown action"
            save_orders(orders)

        requests.post(f"{TG_API}/answerCallbackQuery",
                      data={"callback_query_id": cb_id, "text": "OK"})
        tg_send(chat_id, msg_text)

# ===== ORDER ENDPOINTS =====

@app.route("/api/orders", methods=["POST"])
def create_order():
    data = request.get_json()
    if not data or "items" not in data:
        return jsonify({"error": "Invalid order data"}), 400

    order_id = data.get("id") or "UBS-" + str(int(time.time()))[-8:] + "-" + uuid.uuid4().hex[:3].upper()
    is_bank = data.get("payment") == "bank-transfer" and data.get("paymentBank")

    order = {**data, "id": order_id, "createdAt": datetime.now().isoformat(),
             "status": "awaiting_transfer" if is_bank else "waiting_qris",
             "qrisUrl": None, "telegramMessageId": None, "paidAt": None}

    if BOT_TOKEN and ADMIN_CHAT_ID:
        kb = [[{"text":"✅ Konfirmasi Bayar","callback_data":f"confirm:{order_id}"},
               {"text":"❌ Batalkan","callback_data":f"cancel:{order_id}"}]] if is_bank else \
             [[{"text":"❌ Batalkan","callback_data":f"cancel:{order_id}"}]]
        resp = tg_send(ADMIN_CHAT_ID, format_order_notification(order),
                       reply_markup={"inline_keyboard": kb})
        if resp and resp.get("ok"):
            order["telegramMessageId"] = resp["result"]["message_id"]

    with _orders_lock:
        orders[order_id] = order
        save_orders(orders)

    return jsonify({"id": order_id, "status": order["status"]})


@app.route("/api/orders/<order_id>", methods=["GET"])
def get_order(order_id):
    with _orders_lock:
        order = orders.get(order_id)
    if not order:
        return jsonify({"error": "Order not found"}), 404
    return jsonify({k: v for k, v in order.items() if k != "telegramMessageId"})


@app.route("/api/orders/<order_id>/paid", methods=["POST"])
def mark_paid(order_id):
    with _orders_lock:
        order = orders.get(order_id)
        if not order:
            return jsonify({"error": "Order not found"}), 404
        order["status"] = "paid_pending_verification"
        save_orders(orders)
    if BOT_TOKEN and ADMIN_CHAT_ID:
        tg_send(ADMIN_CHAT_ID,
                f"💸 Customer klaim sudah bayar!\n<code>{order_id}</code>\nTotal: Rp {order['total']:,}",
                reply_markup={"inline_keyboard": [[
                    {"text":"✅ Konfirmasi Diterima","callback_data":f"confirm:{order_id}"},
                    {"text":"❌ Tolak","callback_data":f"reject:{order_id}"},
                ]]})
    return jsonify({"status": order["status"]})


@app.route("/api/orders/<order_id>/proof", methods=["POST"])
def upload_proof(order_id):
    with _orders_lock:
        order = orders.get(order_id)
        if not order:
            return jsonify({"error": "Order not found"}), 404

    if "proof" not in request.files:
        return jsonify({"error": "Tidak ada file"}), 400
    f = request.files["proof"]
    content = f.read()
    if len(content) > 5 * 1024 * 1024:
        return jsonify({"error": "File terlalu besar (maks 5MB)"}), 400
    ext = (f.filename.rsplit(".", 1)[-1] or "").lower()
    if ext not in ("jpg", "jpeg", "png", "webp"):
        return jsonify({"error": "Format harus JPG/PNG/WEBP"}), 400

    proof_dir = Path(__file__).resolve().parent / "proofs"
    proof_dir.mkdir(exist_ok=True)
    (proof_dir / f"{order_id}.{ext}").write_bytes(content)

    with _orders_lock:
        order["status"] = "paid_pending_verification"
        order["proofUploaded"] = True
        save_orders(orders)

    if BOT_TOKEN and ADMIN_CHAT_ID:
        bank = order.get("paymentBank") or {}
        cust = order.get("customer", {})
        caption = (f"🧾 <b>BUKTI TRANSFER</b>\n<code>{order_id}</code>\n\n"
                   f"👤 {cust.get('name','-')}\n"
                   f"🏦 {bank.get('name','-')} - {bank.get('accountNumber','-')}\n"
                   f"💵 <b>Total: Rp {order['total']:,}</b>\n\n<i>Cek bukti, lalu konfirmasi.</i>")
        tg_send_photo(ADMIN_CHAT_ID, content, f"{order_id}.{ext}", caption=caption,
                      reply_markup={"inline_keyboard": [[
                          {"text":"✅ Konfirmasi Diterima","callback_data":f"confirm:{order_id}"},
                          {"text":"❌ Tolak","callback_data":f"reject:{order_id}"},
                      ]]})
    return jsonify({"status": order["status"], "proofUploaded": True})


@app.route("/qris/<filename>")
def serve_qris(filename):
    return send_from_directory(str(QRIS_DIR), filename)

# ===== BANK ENDPOINTS =====

@app.route("/api/banks", methods=["GET"])
def get_banks():
    with _banks_lock:
        active = [b for b in bank_accounts if b.get("active")]
    return jsonify({"banks": active})


@app.route("/api/admin/login", methods=["POST"])
def admin_login():
    data = request.get_json() or {}
    if data.get("password") == ADMIN_PASSWORD:
        return jsonify({"ok": True})
    return jsonify({"ok": False, "error": "Password salah"}), 401


@app.route("/api/admin/banks", methods=["GET"])
def admin_get_banks():
    if not check_admin(request):
        return jsonify({"error": "Unauthorized"}), 401
    return jsonify({"banks": bank_accounts, "supported": SUPPORTED_BANKS})


@app.route("/api/admin/banks", methods=["POST"])
def admin_add_bank():
    if not check_admin(request):
        return jsonify({"error": "Unauthorized"}), 401
    data = request.get_json() or {}
    bank_code = str(data.get("bank_code", "")).strip()
    account_number = str(data.get("accountNumber", "")).strip()
    account_holder = str(data.get("accountHolder", "")).strip()
    bank_info = next((b for b in SUPPORTED_BANKS if b["code"] == bank_code), None)
    if not bank_info:
        return jsonify({"error": "Bank tidak valid"}), 400
    if not account_number or not account_holder:
        return jsonify({"error": "Nomor rekening & nama pemilik wajib diisi"}), 400
    new_bank = {"id": bank_code + "-" + uuid.uuid4().hex[:4], "bank": bank_info["name"],
                "bankCode": bank_code, "logo": f"assets/banks/{bank_code}.png",
                "accountNumber": account_number, "accountHolder": account_holder,
                "active": bool(data.get("active", True))}
    with _banks_lock:
        bank_accounts.append(new_bank)
        save_banks(bank_accounts)
    return jsonify(new_bank), 201


@app.route("/api/admin/banks/<bank_id>", methods=["PUT"])
def admin_update_bank(bank_id):
    if not check_admin(request):
        return jsonify({"error": "Unauthorized"}), 401
    data = request.get_json() or {}
    with _banks_lock:
        bank = next((b for b in bank_accounts if b["id"] == bank_id), None)
        if not bank:
            return jsonify({"error": "Rekening tidak ditemukan"}), 404
        for field in ("accountNumber", "accountHolder", "active"):
            if field in data:
                bank[field] = bool(data[field]) if field == "active" else str(data[field]).strip()
        save_banks(bank_accounts)
    return jsonify(bank)


@app.route("/api/admin/banks/<bank_id>", methods=["DELETE"])
def admin_delete_bank(bank_id):
    if not check_admin(request):
        return jsonify({"error": "Unauthorized"}), 401
    global bank_accounts
    with _banks_lock:
        before = len(bank_accounts)
        bank_accounts = [b for b in bank_accounts if b["id"] != bank_id]
        save_banks(bank_accounts)
        if len(bank_accounts) == before:
            return jsonify({"error": "Rekening tidak ditemukan"}), 404
    return jsonify({"ok": True})

# ===== TESTIMONIAL ENDPOINTS =====

@app.route("/api/testimonials", methods=["GET"])
def get_testimonials():
    with _testi_lock:
        sorted_t = sorted(testimonials, key=lambda t: t.get("createdAt",""), reverse=True)
    limit = request.args.get("limit", type=int)
    if limit:
        sorted_t = sorted_t[:limit]
    avg = round(sum(t.get("rating",0) for t in testimonials) / len(testimonials), 1) if testimonials else 0
    return jsonify({"total": len(testimonials), "items": sorted_t, "averageRating": avg})


@app.route("/api/testimonials", methods=["POST"])
def create_testimonial():
    data = request.get_json()
    if not data:
        return jsonify({"error": "Invalid data"}), 400
    for f in ["name", "rating", "message"]:
        if not data.get(f):
            return jsonify({"error": f"Field '{f}' wajib diisi"}), 400
    rating = int(data.get("rating", 5))
    if not 1 <= rating <= 5:
        return jsonify({"error": "Rating harus 1-5"}), 400
    name = str(data["name"]).strip()
    t = {"id": "T" + uuid.uuid4().hex[:6].upper(), "name": name,
         "initial": (name[0] if name else "?").upper(), "rating": rating,
         "createdAt": datetime.now().isoformat(),
         "title": str(data.get("title","")).strip()[:100],
         "message": str(data["message"]).strip()[:500],
         "product": str(data.get("product","")).strip()[:80],
         "verified": bool(data.get("verified", False))}
    with _testi_lock:
        testimonials.insert(0, t)
        save_testimonials(testimonials)
    if BOT_TOKEN and ADMIN_CHAT_ID:
        tg_send(ADMIN_CHAT_ID,
                f"💬 <b>TESTIMONI BARU</b>\n\n{'⭐'*rating} ({rating}/5)\n"
                f"👤 <b>{t['name']}</b>\n"
                f"{('📦 '+t['product']) if t['product'] else ''}\n\n"
                f"<b>{t.get('title','')}</b>\n<i>{t['message']}</i>")
    return jsonify(t), 201


# ===== STARTUP =====

if __name__ == "__main__":
    if not BOT_TOKEN:
        print("\n⚠️  TELEGRAM_BOT_TOKEN belum di-set di backend/.env\n")
    else:
        print(f"[INFO] Bot: {BOT_TOKEN[:10]}... | Admin: {ADMIN_CHAT_ID}")
        print(f"[INFO] Mode: WEBHOOK — endpoint: {WEBHOOK_DOMAIN}/webhook/telegram")
        print(f"[INFO] Jalankan 'python scripts/setup_webhook.py' untuk daftarkan webhook")

    print(f"[INFO] Backend berjalan di http://localhost:{PORT}")
    print(f"[INFO] Frontend: http://localhost:{PORT}/index.html")
    app.run(host="0.0.0.0", port=PORT, debug=False)
