from __future__ import annotations

from dataclasses import dataclass
from decimal import Decimal
from typing import Any

from market_api.db.sql import qualify_table, quote_identifier
from market_api.tender.common import build_scope_filter, normalize_month


GOVERNMENT_CATEGORY = "政府"
ENTERPRISE_CATEGORY = "企业"
MEANINGLESS_UNIT_KEYWORDS = ("某", "未知", "未披露", "匿名", "不详", "保密", "无名")


@dataclass(frozen=True)
class MajorBuyerRow:
    unit: str
    count: int
    amount_wan: Decimal


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

    def top_buyers(
        self,
        category: str,
        year: int,
        months: list[int],
        scope_filter: tuple[str, str] | None,
    ) -> list[MajorBuyerRow]:
        if not months:
            raise ValueError("统计月份不能为空")

        month_placeholders = ", ".join(["%s"] * len(months))
        unit_column = quote_identifier("招标单位")
        where_parts = [
            f"{quote_identifier('年份')} = %s",
            f"{quote_identifier('月份')} IN ({month_placeholders})",
            f"{quote_identifier('分类')} = %s",
            f"{unit_column} IS NOT NULL",
            f"{unit_column} <> %s",
            *[f"{unit_column} NOT LIKE %s" for _ in MEANINGLESS_UNIT_KEYWORDS],
        ]
        params: list[object] = [
            year,
            *[f"{month}月" for month in months],
            category,
            "",
            *[f"%{keyword}%" for keyword in MEANINGLESS_UNIT_KEYWORDS],
        ]

        if scope_filter is not None:
            column_name, scope_value = scope_filter
            where_parts.append(f"{quote_identifier(column_name)} = %s")
            params.append(scope_value)

        sql = (
            f"SELECT {unit_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 {unit_column} "
            f"ORDER BY amount_wan DESC, tender_count DESC, {unit_column} ASC "
            "LIMIT 10"
        )

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

        return [
            MajorBuyerRow(str(unit), int(count or 0), Decimal(str(amount_wan or 0)))
            for unit, count, amount_wan in rows
        ]


def format_wan_amount(amount: Decimal | int | float | None) -> str:
    value = Decimal("0") if amount is None else Decimal(str(amount))
    return format(value.normalize(), "f")


def _report_rows(rows: list[MajorBuyerRow]) -> list[dict[str, object]]:
    return [
        {
            "招标单位": row.unit,
            "招标次数": row.count,
            "招标预算金额（万元）": format_wan_amount(row.amount_wan),
        }
        for row in rows
    ]


def build_major_buyers_summary(
    repository: object,
    year: int,
    month: str | int,
    scope: str,
    scope_value: str | None,
) -> dict[str, object]:
    month_number = normalize_month(month)
    normalized_scope_value = scope_value.strip() if scope_value is not None else None
    scope_filter = build_scope_filter(scope, normalized_scope_value)
    months = list(range(1, month_number + 1))

    government_rows = repository.top_buyers(
        GOVERNMENT_CATEGORY,
        year,
        months,
        scope_filter,
    )
    enterprise_rows = repository.top_buyers(
        ENTERPRISE_CATEGORY,
        year,
        months,
        scope_filter,
    )

    return {
        "统计年份": year,
        "统计月份": f"{month_number}月",
        "统计方式": scope,
        "统计参数": normalized_scope_value if scope != "上海" else None,
        "政府侧招标单位": _report_rows(government_rows),
        "企业侧招标单位": _report_rows(enterprise_rows),
    }
