from __future__ import annotations

import json
import re
from datetime import date
from http import HTTPStatus
from urllib.parse import parse_qs


class ScreenerRoutesMixin:
    def _handle_screener_get(self, parsed) -> bool:
        if parsed.path == "/api/screener/setup":
            query = parse_qs(parsed.query)
            trade_date = query.get("trade_date", [date.today().isoformat()])[0]
            try:
                self.send_json(self.application_service.screener_setup(trade_date))
            except ValueError as exc:
                self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
            return True
        if parsed.path == "/api/screener/tracking":
            query = parse_qs(parsed.query)
            try:
                self.send_json(
                    self.application_service.screener_tracking(int(query.get("limit", ["12"])[0]))
                )
            except (TypeError, ValueError) as exc:
                self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
            return True
        return False

    def _handle_screener_post(self, parsed) -> bool:
        if parsed.path == "/api/screener/tracking":
            try:
                result = self.application_service.add_screener_tracking(self.read_json_body())
                self.send_json({"ok": True, **result})
            except (ValueError, json.JSONDecodeError) as exc:
                self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
            return True
        return False

    def _handle_screener_delete(self, parsed) -> bool:
        strategy_match = re.fullmatch(r"/api/screener/strategies/(\d+)", parsed.path)
        if strategy_match:
            try:
                result = self.application_service.delete_screener_strategy(int(strategy_match.group(1)))
                self.send_json({"ok": True, **result})
            except ValueError as exc:
                self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
            return True
        tracking_match = re.fullmatch(r"/api/screener/tracking/(\d+)", parsed.path)
        if tracking_match:
            result = self.application_service.remove_screener_tracking(int(tracking_match.group(1)))
            self.send_json({"ok": True, **result})
            return True
        return False

    def sync_screener_data(self) -> None:
        try:
            body = self.read_json_body()
            result = self.application_service.sync_screener_data(
                str(body.get("trade_date") or date.today().isoformat()),
                int(body.get("lookback") or 45),
            )
            self.send_json({"ok": True, "result": result})
        except ValueError as exc:
            self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
        except Exception as exc:
            self.send_json({"error": f"因子数据同步失败：{exc}"}, HTTPStatus.INTERNAL_SERVER_ERROR)

    def compile_screener_strategy(self) -> None:
        try:
            body = self.read_json_body()
            result = self.application_service.compile_screener_strategy(
                str(body.get("prompt") or ""), str(body.get("regime") or "")
            )
            self.send_json({"ok": True, "strategy": result})
        except ValueError as exc:
            self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)

    def save_screener_strategy(self) -> None:
        try:
            body = self.read_json_body()
            result = self.application_service.save_screener_strategy(body)
            self.send_json({"ok": True, **result})
        except ValueError as exc:
            self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)

    def run_screener(self) -> None:
        try:
            body = self.read_json_body()
            result = self.application_service.run_screener(body)
            self.send_json({"ok": True, "result": result})
        except ValueError as exc:
            self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
        except Exception as exc:
            self.send_json({"error": f"选股执行失败：{exc}"}, HTTPStatus.INTERNAL_SERVER_ERROR)

    def refresh_screener_tracking(self) -> None:
        try:
            body = self.read_json_body(True)
            trade_date = str(body.get("trade_date") or date.today().isoformat())
            self.send_json({"ok": True, **self.application_service.refresh_screener_tracking(trade_date)})
        except (ValueError, json.JSONDecodeError) as exc:
            self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
        except Exception as exc:
            self.send_json({"error": f"跟踪刷新失败：{exc}"}, HTTPStatus.INTERNAL_SERVER_ERROR)
