from __future__ import annotations

from decimal import Decimal
from typing import Any

from market_api.award.common import build_ct_filter, format_share, format_wan_amount
from market_api.award.industry import REPORT_OPERATORS
from market_api.award.overall import (
    OPERATOR_AMOUNT_COLUMNS,
    OPERATORS,
    AwardOperatorAggregate,
)
from market_api.db.sql import qualify_table, quote_identifier
from market_api.tender.common import normalize_month


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


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

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

        month_placeholders = ", ".join(["%s"] * len(months))
        region_placeholders = ", ".join(["%s"] * len(AWARD_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],
            *AWARD_REGIONS,
        ]

        ct_value = ct_filter[0]
        ct_column = quote_identifier("CT类")
        if ct_value == "是":
            where_parts.append(f"{ct_column} IS NOT NULL")
            where_parts.append(f"{ct_column} <> %s")
            params.append("")
        else:
            where_parts.append(f"{ct_column} = %s")
            params.append("否")

        select_parts = [region_column]
        for operator in OPERATORS:
            amount_column = quote_identifier(OPERATOR_AMOUNT_COLUMNS[operator])
            select_parts.append(f"COUNT({amount_column})")
            select_parts.append(f"COALESCE(SUM({amount_column}), 0)")

        sql = (
            f"SELECT {', '.join(select_parts)} "
            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()

        result: dict[str, dict[str, AwardOperatorAggregate]] = {}
        for row in rows:
            region = str(row[0])
            result[region] = {
                operator: AwardOperatorAggregate(
                    int(row[index * 2 + 1] or 0),
                    Decimal(str(row[index * 2 + 2] or 0)),
                )
                for index, operator in enumerate(OPERATORS)
            }
        return result


def validate_award_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 _empty_operator_aggregate() -> AwardOperatorAggregate:
    return AwardOperatorAggregate(0, Decimal("0"))


def _share(value: Decimal | int, total: Decimal | int) -> Decimal | None:
    total_value = Decimal(str(total))
    if total_value == 0:
        return None
    return Decimal(str(value)) / total_value * Decimal("100")


def _count_row(
    region: str,
    operator_data: dict[str, AwardOperatorAggregate],
) -> dict[str, object]:
    total_count = sum(
        operator_data.get(operator, _empty_operator_aggregate()).count
        for operator in OPERATORS
    )
    row: dict[str, object] = {"属地": region}
    for operator in REPORT_OPERATORS:
        current = operator_data.get(operator, _empty_operator_aggregate())
        row[f"{operator}个数"] = current.count
    for operator in REPORT_OPERATORS:
        current = operator_data.get(operator, _empty_operator_aggregate())
        row[f"{operator}个数份额"] = format_share(_share(current.count, total_count))
    return row


def _amount_row(
    region: str,
    operator_data: dict[str, AwardOperatorAggregate],
) -> dict[str, object]:
    total_amount = sum(
        operator_data.get(operator, _empty_operator_aggregate()).amount_wan
        for operator in OPERATORS
    )
    row: dict[str, object] = {"属地": region}
    for operator in REPORT_OPERATORS:
        current = operator_data.get(operator, _empty_operator_aggregate())
        row[f"{operator}金额（万元）"] = format_wan_amount(current.amount_wan)
    for operator in REPORT_OPERATORS:
        current = operator_data.get(operator, _empty_operator_aggregate())
        row[f"{operator}金额份额"] = format_share(_share(current.amount_wan, total_amount))
    return row


def _region_rows(
    current_by_region: dict[str, dict[str, AwardOperatorAggregate]],
) -> dict[str, list[dict[str, object]]]:
    count_rows: list[dict[str, object]] = []
    amount_rows: list[dict[str, object]] = []
    for region in AWARD_REGIONS:
        operator_data = current_by_region.get(region, {})
        count_rows.append(_count_row(region, operator_data))
        amount_rows.append(_amount_row(region, operator_data))
    return {"个数数据": count_rows, "金额数据": amount_rows}


def build_award_region_summary(
    repository: object,
    year: int,
    month: str | int,
    ct: str,
    scope: str,
    scope_value: str | None,
) -> dict[str, object]:
    validate_award_region_scope(scope, scope_value)
    month_number = normalize_month(month)
    ct_filter = build_ct_filter(ct)
    normalized_ct = ct_filter[0]

    cumulative_months = list(range(1, month_number + 1))
    cumulative = repository.aggregate_by_region(
        year,
        cumulative_months,
        ct_filter,
    )
    monthly = repository.aggregate_by_region(
        year,
        [month_number],
        ct_filter,
    )

    return {
        "统计年份": year,
        "统计月份": f"{month_number}月",
        "统计CT": normalized_ct,
        "统计方式": scope,
        "统计参数": None,
        "累计数据": _region_rows(cumulative),
        "月度数据": _region_rows(monthly),
    }
