# source: https://raw.githubusercontent.com/xegheplimo-web/USDT-Binance/d431c1a72f127f7270c809348d588c102f94d5f8/backend/app/services/config_exporter.py
"""DuyAI Config Studio — export a downloadable config bundle.

Produces 4 text artefacts the user can save to disk:
  * ``config.json``       — Freqtrade config (sanitised: API keys stripped)
  * ``strategy.py``       — Strategy skeleton with protections + leverage()
  * ``docker-compose.yml`` — Docker Compose with env-var secret injection
  * ``.env.example``      — Environment variables template
  * ``README.md``         — Quick-start guide in Vietnamese

The exporter never writes to disk — it returns strings so the API endpoint can
stream them as a JSON response or a zip download.
"""
from __future__ import annotations

import json
from typing import Any

from app.schemas import ConfigExportRequest, ConfigExportResult

# ---------------------------------------------------------------------------
# Default strategy skeleton (matches the DuyAI Futures 5m guide)
# ---------------------------------------------------------------------------

_STRATEGY_TEMPLATE = '''\
"""DuyAI Futures 5m — strategy skeleton generated by DuyAI Config Studio.

Cấu hình khuyến nghị cho Binance USDT-M Futures, khung 5m, Long/Short,
ưu tiên an toàn. Thêm logic entry/exit của bạn vào populate_entry_trend /
populate_exit_trend trước khi chạy live.
"""
from datetime import datetime
from typing import Optional

from freqtrade.strategy import IStrategy


class Github_xegheplimo_web_USDT_Binance__config_exporter__20260719_230807(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = "{timeframe}"
    can_short = {can_short}
    process_only_new_candles = True
    startup_candle_count = 400

    position_adjustment_enable = False
    max_open_trades = {max_open_trades}

    stoploss = {stoploss}

    trailing_stop = {trailing_stop}
    trailing_stop_positive = {trailing_stop_positive}
    trailing_stop_positive_offset = {trailing_stop_positive_offset}
    trailing_only_offset_is_reached = True

    minimal_roi = {minimal_roi}

    @property
    def protections(self) -> list[dict]:
        return {protections}

    def leverage(
        self,
        pair: str,
        current_time: datetime,
        current_rate: float,
        proposed_leverage: float,
        max_leverage: float,
        entry_tag: Optional[str],
        side: str,
        **kwargs,
    ) -> float:
        """Leverage an toàn mặc định.

        BTC/ETH: tối đa {lev_major}x.
        Altcoin: tối đa {lev_alt}x.
        """
        major_pairs = {{"BTC/USDT:USDT", "ETH/USDT:USDT"}}
        requested = {lev_major}.0 if pair in major_pairs else {lev_alt}.0
        return max(1.0, min(requested, max_leverage))

    def populate_entry_trend(self, dataframe, metadata):
        # TODO: thêm logic entry của bạn
        dataframe.loc[
            (),
            ["enter_long", "enter_tag"],
        ] = ((), ())
        return dataframe

    def populate_exit_trend(self, dataframe, metadata):
        # TODO: thêm logic exit của bạn
        return dataframe
'''

_DOCKER_TEMPLATE = '''\
services:
  freqtrade:
    image: freqtradeorg/freqtrade:stable
    container_name: freqtrade-{bot_slug}
    restart: unless-stopped
    volumes:
      - "./user_data:/freqtrade/user_data"
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      TZ: "Asia/Bangkok"
      FREQTRADE__EXCHANGE__KEY: "${{BINANCE_API_KEY}}"
      FREQTRADE__EXCHANGE__SECRET: "${{BINANCE_API_SECRET}}"
      FREQTRADE__API_SERVER__JWT_SECRET_KEY: "${{FREQTRADE_JWT_SECRET}}"
      FREQTRADE__API_SERVER__PASSWORD: "${{FREQTRADE_UI_PASSWORD}}"
      FREQTRADE__API_SERVER__WS_TOKEN: "${{FREQTRADE_WS_TOKEN}}"
    command:
      - trade
      - --logfile
      - /freqtrade/user_data/logs/freqtrade.log
      - --config
      - /freqtrade/user_data/config.json
      - --strategy
      - {strategy_name}
'''

_ENV_TEMPLATE = '''\
# DuyAI Freqtrade Configuration Studio — .env example
# Điền giá trị thật trước khi chạy docker compose up.

BINANCE_API_KEY=YOUR_BINANCE_API_KEY
BINANCE_API_SECRET=YOUR_BINANCE_API_SECRET

FREQTRADE_JWT_SECRET=GENERATE_A_RANDOM_SECRET_LONGER_THAN_64_CHARACTERS
FREQTRADE_UI_PASSWORD=USE_A_LONG_UNIQUE_PASSWORD
FREQTRADE_WS_TOKEN=GENERATE_A_LONG_RANDOM_WEBSOCKET_TOKEN
'''

_README_TEMPLATE = '''\
# DuyAI Futures 5m — Cấu hình Freqtrade

Bộ cấu hình được sinh bởi **DuyAI Freqtrade Configuration Studio**.

## Files

| File | Mục đích |
|---|---|
| `user_data/config.json` | Cấu hình chính của bot |
| `user_data/strategies/{strategy_name}.py` | Strategy skeleton |
| `docker-compose.yml` | Docker Compose cho Freqtrade + FreqUI |
| `.env` | Biến môi trường (API key, JWT secret…) |

## Khởi động nhanh

```bash
# 1. Điền .env
cp .env.example .env
# sửa BINANCE_API_KEY, BINANCE_API_SECRET, FREQTRADE_JWT_SECRET…

# 2. Khởi động container
docker compose pull
docker compose up -d
docker compose logs -f

# 3. Kiểm tra config
docker compose run --rm freqtrade show-config \\
  --config /freqtrade/user_data/config.json

# 4. Kiểm tra pairlist
docker compose run --rm freqtrade test-pairlist \\
  --config /freqtrade/user_data/config.json

# 5. Tải dữ liệu lịch sử
docker compose run --rm freqtrade download-data \\
  --config /freqtrade/user_data/config.json \\
  --trading-mode futures \\
  --timeframes 1m 5m 15m 1h \\
  --days 730

# 6. Backtest
docker compose run --rm freqtrade backtesting \\
  --config /freqtrade/user_data/config.json \\
  --strategy {strategy_name} \\
  --timerange 20240701-20260701 \\
  --timeframe-detail 1m \\
  --enable-protections
```

## Checklist trước khi live

- [ ] Dry-run tối thiểu 2–4 tuần
- [ ] Backtest ≥ 2 năm với `--enable-protections`
- [ ] API key Binance: chỉ Read + Futures trading, KHÔNG bật Withdraw
- [ ] Đổi toàn bộ `CHANGE_THIS_*` trong config
- [ ] Binance: One-way Mode, Single-Asset Mode, Isolated Margin
- [ ] Không public FreqUI ra Internet — dùng VPN/SSH tunnel/reverse proxy

> Đây không phải lời khuyên đầu tư. Tự chịu trách nhiệm với vốn của mình.
'''

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _slugify(name: str) -> str:
    return "".join(c.lower() if c.isalnum() else "-" for c in name).strip("-") or "freqtrade"


def _sanitize_config(config: dict[str, Any]) -> dict[str, Any]:
    """Strip plaintext API keys so the exported config.json is safe to share."""
    out = dict(config)
    ex = dict(out.get("exchange", {}))
    ex["key"] = ""
    ex["secret"] = ""
    out["exchange"] = ex
    api = dict(out.get("api_server", {}))
    # Replace placeholder secrets with env-var references
    api["jwt_secret_key"] = "${FREQTRADE_JWT_SECRET}"
    api["password"] = "${FREQTRADE_UI_PASSWORD}"
    api["ws_token"] = "${FREQTRADE_WS_TOKEN}"
    out["api_server"] = api
    return out


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def export_bundle(req: ConfigExportRequest) -> ConfigExportResult:
    """Build the 4-file export bundle from a config + strategy_config."""
    config = _sanitize_config(req.config)
    sc = req.strategy_config or {}

    # --- config.json ---
    config_json = json.dumps(config, indent=2, ensure_ascii=False)

    # --- strategy.py ---
    protections = sc.get("protections", [])
    lev = sc.get("leverage", {})
    if isinstance(lev, dict):
        lev_major = lev.get("major_pairs", 3)
        lev_alt = lev.get("altcoin", 2)
    else:
        lev_major = lev_alt = lev

    strategy_py = _STRATEGY_TEMPLATE.format(
        class_name=req.strategy_name,
        timeframe=config.get("timeframe", "5m"),
        can_short=config.get("trading_mode") == "futures",
        max_open_trades=config.get("max_open_trades", 4),
        stoploss=config.get("stoploss", -0.06),
        trailing_stop=config.get("trailing_stop", True),
        trailing_stop_positive=config.get("trailing_stop_positive", 0.012),
        trailing_stop_positive_offset=config.get("trailing_stop_positive_offset", 0.025),
        minimal_roi=sc.get("minimal_roi", {
            "0": 0.04, "30": 0.025, "60": 0.015, "120": 0.005, "240": 0.0,
        }),
        protections=repr(protections) if protections else "[]",
        lev_major=lev_major,
        lev_alt=lev_alt,
    )

    # --- docker-compose.yml ---
    docker_compose: str | None = None
    if req.include_docker:
        bot_slug = _slugify(config.get("bot_name", "duyai-futures"))
        docker_compose = _DOCKER_TEMPLATE.format(
            bot_slug=bot_slug,
            strategy_name=req.strategy_name,
        )

    # --- .env.example ---
    env_example = _ENV_TEMPLATE

    # --- README.md ---
    readme = _README_TEMPLATE.format(strategy_name=req.strategy_name)

    return ConfigExportResult(
        config_json=config_json,
        strategy_py=strategy_py,
        docker_compose=docker_compose,
        env_example=env_example,
        readme=readme,
    )
