from __future__ import annotations

from decimal import Decimal
from typing import Any

from market_api.db.sql import qualify_table, quote_identifier
from market_api.tender.common import (
    TenderAggregate,
    format_growth,
    format_yi_yuan,
    normalize_month,
)


REGIONS = (
    "战客",
    "浦东",
    "南区",
    "西区",
    "北区",
    "闵行",
    "松江",
    "宝山",
    "青浦",
    "奉贤",
    "嘉定",
    "金山",
    "崇明",
    "互拓",
    "其他",
)

EMPTY_AGGREGATE = TenderAggregate(0, Decimal("0"))


class TenderRegionRepository:
    def __init__(self, conn: Any, schema: str):
        self.conn = conn
        self.schema = schema

    def aggregate_by_region(self, year: int, months: list[int]) -> dict[str, TenderAggregate]:
        if not months:
            raise ValueError("统计月份不能为空")

        month_placeholders = ", ".join(["%s"] * len(months))
        region_placeholders = ", ".join(["%s"] * len(REGIONS))
        region_column = quote_identifier("归属区域_属地")
        where_parts = [
            f"{quote_identifier('年份')} = %s",
            f"{quote_identifier('月份')} IN ({month_placeholders})",
            f"{region_column} IN ({region_placeholders})",
        ]
        params: list[object] = [
            year,
            *[f"{month}月" for month in months],
            *REGIONS,
        ]

        sql = (
            f"SELECT {region_column}, COUNT(*) AS tender_count, "
            f"COALESCE(SUM({quote_identifier('预算金额_万元')}), 0) AS amount_wan "
            f"FROM {qualify_table(self.schema, '公开市场招标数据')} "
            f"WHERE {' AND '.join(where_parts)} "
            f"GROUP BY {region_column}"
        )

        with self.conn.cursor() as cursor:
            cursor.execute(sql, params)
            rows = cursor.fetchall()

        return {
            str(region): TenderAggregate(int(count or 0), Decimal(str(amount_wan or 0)))
            for region, count, amount_wan in rows
        }


def validate_region_scope(scope: str, scope_value: str | None) -> None:
    if scope != "上海":
        raise ValueError("区域招标分析仅支持统计方式为上海")
    if scope_value is not None and scope_value.strip():
        raise ValueError("区域招标分析的统计参数必须留空")


def _region_row(
    region: str,
    current: TenderAggregate,
    baseline: TenderAggregate | None,
    count_growth_key: str,
    amount_growth_key: str,
) -> dict[str, object]:
    if baseline is None:
        count_growth = "/"
        amount_growth = "/"
    else:
        count_growth = format_growth(current.count, baseline.count)
        amount_growth = format_growth(current.amount_wan, baseline.amount_wan)

    return {
        "属地": region,
        "个数": current.count,
        "金额（亿元）": format_yi_yuan(current.amount_wan),
        count_growth_key: count_growth,
        amount_growth_key: amount_growth,
    }


def _region_rows(
    current_by_region: dict[str, TenderAggregate],
    baseline_by_region: dict[str, TenderAggregate] | None,
    count_growth_key: str,
    amount_growth_key: str,
) -> list[dict[str, object]]:
    rows: list[dict[str, object]] = []
    for region in REGIONS:
        current = current_by_region.get(region, EMPTY_AGGREGATE)
        baseline = (
            None
            if baseline_by_region is None
            else baseline_by_region.get(region, EMPTY_AGGREGATE)
        )
        rows.append(_region_row(region, current, baseline, count_growth_key, amount_growth_key))
    return rows


def build_region_summary(
    repository: object,
    year: int,
    month: str | int,
    scope: str,
    scope_value: str | None,
) -> dict[str, object]:
    validate_region_scope(scope, scope_value)
    month_number = normalize_month(month)

    cumulative_months = list(range(1, month_number + 1))
    current_cumulative = repository.aggregate_by_region(year, cumulative_months)
    baseline_cumulative = repository.aggregate_by_region(year - 1, cumulative_months)
    current_monthly = repository.aggregate_by_region(year, [month_number])

    if month_number == 1:
        previous_monthly = None
    else:
        previous_monthly = repository.aggregate_by_region(year, [month_number - 1])

    return {
        "统计年份": year,
        "统计月份": f"{month_number}月",
        "统计方式": "上海",
        "统计参数": None,
        "累计数据": _region_rows(
            current_cumulative,
            baseline_cumulative,
            "个数同比增幅",
            "金额同比增幅",
        ),
        "月度数据": _region_rows(
            current_monthly,
            previous_monthly,
            "个数环比增幅",
            "金额环比增幅",
        ),
    }
