from __future__ import annotations

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

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


TELECOM_AMOUNT_COLUMN = "电信金额_万元"
UNICOM_AMOUNT_COLUMN = "联通金额_万元"
LARGE_DEAL_THRESHOLD_WAN = Decimal("300")
ALLOWED_AMOUNT_COLUMNS = {TELECOM_AMOUNT_COLUMN, UNICOM_AMOUNT_COLUMN}


@dataclass(frozen=True)
class CompetitorLargeDealRow:
    buyer: str
    industry: str
    project_name: str
    amount_wan: Decimal


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

    def large_deals(
        self,
        amount_column: str,
        year: int,
        month: int,
        ct_filter: tuple[str, ...],
        scope_filter: tuple[str, str] | None,
    ) -> list[CompetitorLargeDealRow]:
        if amount_column not in ALLOWED_AMOUNT_COLUMNS:
            raise ValueError("不支持的大单金额字段")

        quoted_amount_column = quote_identifier(amount_column)
        where_parts = [
            f"{quote_identifier('年份')} = %s",
            f"{quote_identifier('月份')} = %s",
        ]
        params: list[object] = [year, f"{month}月"]

        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("否")

        where_parts.append(f"{quoted_amount_column} > %s")
        params.append(LARGE_DEAL_THRESHOLD_WAN)

        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)

        buyer_column = quote_identifier("招标人")
        industry_column = quote_identifier("行业")
        project_column = quote_identifier("项目名称")
        sql = (
            f"SELECT {buyer_column}, {industry_column}, {project_column}, "
            f"{quoted_amount_column} "
            f"FROM {qualify_table(self.schema, '运营商市场中标数据')} "
            f"WHERE {' AND '.join(where_parts)} "
            f"ORDER BY {quoted_amount_column} DESC, {buyer_column} ASC, "
            f"{project_column} ASC"
        )

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

        return [
            CompetitorLargeDealRow(
                str(buyer or ""),
                str(industry or ""),
                str(project_name or ""),
                Decimal(str(amount_wan or 0)),
            )
            for buyer, industry, project_name, amount_wan in rows
        ]


def _deal_rows(rows: list[CompetitorLargeDealRow]) -> list[dict[str, object]]:
    return [
        {
            "招标人": row.buyer,
            "行业": row.industry,
            "项目名称": row.project_name,
            "中标金额（万元）": format_wan_amount(row.amount_wan),
        }
        for row in rows
    ]


def build_competitor_large_deals_summary(
    repository: object,
    year: int,
    month: str | int,
    ct: str,
    scope: str,
    scope_value: str | None,
) -> dict[str, object]:
    month_number = normalize_month(month)
    ct_filter = build_ct_filter(ct)
    normalized_ct = ct_filter[0]
    normalized_scope_value = scope_value.strip() if scope_value is not None else None
    scope_filter = build_scope_filter(scope, normalized_scope_value)

    telecom_rows = repository.large_deals(
        TELECOM_AMOUNT_COLUMN,
        year,
        month_number,
        ct_filter,
        scope_filter,
    )
    unicom_rows = repository.large_deals(
        UNICOM_AMOUNT_COLUMN,
        year,
        month_number,
        ct_filter,
        scope_filter,
    )

    return {
        "统计年份": year,
        "统计月份": f"{month_number}月",
        "统计CT": normalized_ct,
        "统计方式": scope,
        "统计参数": normalized_scope_value if scope != "上海" else None,
        "电信大单": _deal_rows(telecom_rows),
        "联通大单": _deal_rows(unicom_rows),
    }
