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,
    build_scope_filter,
    format_growth,
    format_yi_yuan,
    normalize_month,
)


INDUSTRIES = (
    "党政",
    "金融",
    "教育",
    "工业能源",
    "医卫",
    "交通",
    "商客",
    "农业文旅",
    "互联网",
    "融合创新",
)

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


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

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

        month_placeholders = ", ".join(["%s"] * len(months))
        industry_placeholders = ", ".join(["%s"] * len(INDUSTRIES))
        where_parts = [
            f"{quote_identifier('年份')} = %s",
            f"{quote_identifier('月份')} IN ({month_placeholders})",
            f"{quote_identifier('行业')} IN ({industry_placeholders})",
        ]
        params: list[object] = [
            year,
            *[f"{month}月" for month in months],
            *INDUSTRIES,
        ]

        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)

        industry_column = quote_identifier("行业")
        sql = (
            f"SELECT {industry_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 {industry_column}"
        )

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

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


def _industry_row(
    industry: 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 {
        "行业": industry,
        "个数": current.count,
        "金额（亿元）": format_yi_yuan(current.amount_wan),
        count_growth_key: count_growth,
        amount_growth_key: amount_growth,
    }


def _industry_rows(
    current_by_industry: dict[str, TenderAggregate],
    baseline_by_industry: dict[str, TenderAggregate] | None,
    count_growth_key: str,
    amount_growth_key: str,
) -> list[dict[str, object]]:
    rows: list[dict[str, object]] = []
    for industry in INDUSTRIES:
        current = current_by_industry.get(industry, EMPTY_AGGREGATE)
        baseline = (
            None
            if baseline_by_industry is None
            else baseline_by_industry.get(industry, EMPTY_AGGREGATE)
        )
        rows.append(_industry_row(industry, current, baseline, count_growth_key, amount_growth_key))
    return rows


def build_industry_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)

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

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

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