"""
Build an ecosystem partner overlap finder in Google Sheets.
"""

from __future__ import annotations

import logging
from collections import defaultdict
from typing import Any, Dict, List, Optional, Tuple

from g_gremlin.a1 import parse_a1_range
from g_gremlin.normalize import normalize_domain as normalize_domain_basic
from g_gremlin.normalize import normalize_name

logger = logging.getLogger(__name__)


def _inputs_to_dict(inputs: Any) -> Dict[str, Any]:
    if hasattr(inputs, "dict"):
        return inputs.dict()
    if isinstance(inputs, dict):
        return inputs
    return dict(inputs)


def _escape_soql_literal(value: str) -> str:
    return str(value).replace("\\", "\\\\").replace("'", "\\'")


def _normalize_values(values: Any) -> List[str]:
    if values is None:
        return []
    if isinstance(values, str):
        raw = values.split(",")
        return [v.strip() for v in raw if v and v.strip()]
    if isinstance(values, (list, tuple, set)):
        return [str(v).strip() for v in values if str(v).strip()]
    return [str(values).strip()] if str(values).strip() else []


def _build_filter_clause(field: str, values: List[str], field_type: str) -> str:
    field = str(field or "").strip()
    if not field:
        raise ValueError("Filter field is required.")

    ftype = (field_type or "picklist").strip().lower()
    if ftype == "boolean":
        flag = True
        if values:
            raw = str(values[0]).strip().lower()
            flag = raw in {"true", "1", "yes", "y", "t"}
        return f"{field} = {'TRUE' if flag else 'FALSE'}"

    if not values:
        raise ValueError(f"Filter values required for field '{field}'.")

    rendered: List[str] = []
    for val in values:
        raw = str(val).strip()
        if not raw:
            continue
        rendered.append(f"'{_escape_soql_literal(raw)}'")

    if not rendered:
        raise ValueError(f"Filter values required for field '{field}'.")

    return f"{field} IN ({', '.join(rendered)})"


def _normalize_domain(value: Optional[str]) -> str:
    if not value:
        return ""
    basic = normalize_domain_basic(value)
    if not basic:
        return ""
    try:
        from fmatch.core.normalization.domain import normalize_domain as normalize_registrable
    except Exception:
        normalize_registrable = None
    if normalize_registrable:
        normalized = normalize_registrable(basic)
        return normalized or basic
    return basic


def _normalize_name(value: Optional[str]) -> str:
    return normalize_name(str(value or ""))


def _classify_partner_segment(value: Optional[str]) -> Tuple[bool, bool]:
    text = str(value or "").strip().lower()
    if not text:
        return False, False
    is_customer = "customer" in text or "client" in text
    is_prospect = "prospect" in text or "lead" in text or "target" in text
    return is_customer, is_prospect


def _determine_opportunity_type(
    partner_is_customer: bool,
    partner_is_prospect: bool,
    our_is_customer: bool,
    our_is_prospect: bool,
) -> str:
    if partner_is_customer and our_is_prospect:
        return "Co-sell"
    if partner_is_prospect and our_is_customer:
        return "Referral"
    if (partner_is_customer and our_is_customer) or (partner_is_prospect and our_is_prospect):
        return "Overlap"
    return "None"


def _confidence_label(score: float) -> str:
    if score >= 0.9:
        return "High"
    if score >= 0.8:
        return "Med"
    return "Low"


def _col_letter(idx: int) -> str:
    result = ""
    idx_val = idx
    while True:
        idx_val, rem = divmod(idx_val, 26)
        result = chr(ord("A") + rem) + result
        if idx_val == 0:
            break
        idx_val -= 1
    return result


def _quote_tab(tab_name: str) -> str:
    """Escape single quotes in tab names for sheet references."""
    escaped = tab_name.replace("'", "''")
    return f"'{escaped}'"


def _sheet_cell(tab_name: str, cell_ref: str) -> str:
    """Build a quoted sheet cell reference."""
    return f"{_quote_tab(tab_name)}!{cell_ref}"


def _pick_arr_field(fields: List[str]) -> Optional[str]:
    for field in fields:
        name = str(field or "").lower()
        if "arr" in name or "revenue" in name:
            return field
    return None


def _ensure_sheet(service, spreadsheet_id: str, sheet_name: str, replace: bool = False) -> int:
    try:
        ss = service.spreadsheets().get(spreadsheetId=spreadsheet_id).execute()
        for sheet in ss.get("sheets", []):
            if sheet["properties"]["title"] == sheet_name:
                if replace:
                    sheet_id = sheet["properties"]["sheetId"]
                    service.spreadsheets().batchUpdate(
                        spreadsheetId=spreadsheet_id,
                        body={"requests": [{"deleteSheet": {"sheetId": sheet_id}}]},
                    ).execute()
                    break
                return sheet["properties"]["sheetId"]
    except Exception:
        pass

    resp = service.spreadsheets().batchUpdate(
        spreadsheetId=spreadsheet_id,
        body={"requests": [{"addSheet": {"properties": {"title": sheet_name}}}]},
    ).execute()
    return resp["replies"][0]["addSheet"]["properties"]["sheetId"]


def _write_rows(service, spreadsheet_id: str, sheet_name: str, rows: List[List[Any]]) -> None:
    if not rows:
        return
    num_cols = max(len(row) for row in rows)
    end_col = _col_letter(num_cols - 1)
    range_str = f"{sheet_name}!A1:{end_col}{len(rows)}"
    padded_rows = []
    for row in rows:
        padded_rows.append(list(row) + [""] * (num_cols - len(row)))
    service.spreadsheets().values().update(
        spreadsheetId=spreadsheet_id,
        range=range_str,
        valueInputOption="USER_ENTERED",
        body={"values": padded_rows},
    ).execute()


async def _fetch_records(sf_client, soql: str) -> List[Dict[str, Any]]:
    records: List[Dict[str, Any]] = []
    if hasattr(sf_client, "paginate_soql"):
        async for batch in sf_client.paginate_soql(soql):
            if isinstance(batch, list):
                records.extend(batch)
            elif isinstance(batch, dict):
                records.extend(batch.get("records", []) or [])
    else:
        result = await sf_client.soql(soql)
        records.extend(result.get("records", []) or [])
    for record in records:
        record.pop("attributes", None)
    return records


async def _resolve_match_gateway(match_gateway: Any):
    if match_gateway is not None:
        return match_gateway
    try:
        from fmatch.saas.services.match_gateway import MatchGateway

        return await MatchGateway.create()
    except Exception:
        return None


def _best_matches_by_source(matches_df, threshold: float) -> Dict[int, Tuple[int, float]]:
    if matches_df is None or matches_df.empty:
        return {}
    df = matches_df.copy()
    if "score" not in df.columns:
        if "confidence_score" in df.columns:
            df["score"] = df["confidence_score"]
        elif "match_score" in df.columns:
            df["score"] = df["match_score"]
        else:
            df["score"] = 0.0
    if df["score"].max() > 1.0:
        df["score"] = df["score"] / 100.0
    df = df.sort_values("score", ascending=False)
    best = df.drop_duplicates(subset=["source_id"], keep="first")
    output: Dict[int, Tuple[int, float]] = {}
    for _, row in best.iterrows():
        source_id = row.get("source_id")
        reference_id = row.get("reference_id")
        score = float(row.get("score") or 0.0)
        if source_id is None or reference_id is None or score < threshold:
            continue
        try:
            output[int(source_id)] = (int(reference_id), score)
        except (TypeError, ValueError):
            continue
    return output


async def _run_fuzzy_match(
    partner_names: List[str],
    account_names: List[str],
    threshold: float,
    match_gateway: Any,
) -> Dict[int, Tuple[int, float]]:
    if not partner_names or not account_names:
        return {}
    gateway = await _resolve_match_gateway(match_gateway)
    try:
        import pandas as pd
    except Exception:
        gateway = None

    if gateway and "pd" in locals():
        source_df = pd.DataFrame({"normalized_name": partner_names})
        reference_df = pd.DataFrame({"normalized_name": account_names})
        mappings = [
            {
                "source": "normalized_name",
                "reference": "normalized_name",
                "weight": 1.0,
                "algorithm": "WRatio",
            }
        ]
        result = await gateway.match(
            source_df,
            reference_df,
            source_col="normalized_name",
            target_col="normalized_name",
            threshold=threshold,
            mappings=mappings,
        )
        return _best_matches_by_source(result.matches if result else None, threshold)

    try:
        from fmatch.core.matcher import FuzzyMatcher
        import pandas as pd
    except Exception:
        return {}

    source_df = pd.DataFrame({"normalized_name": partner_names})
    reference_df = pd.DataFrame({"normalized_name": account_names})
    matcher = FuzzyMatcher(mode="match")
    matcher.add_mapping(
        "normalized_name", "normalized_name", weight=1.0, algorithm="WRatio"
    )
    matcher.set_threshold(int(threshold * 100))
    matches_df = matcher.match(source_df, reference_df)
    return _best_matches_by_source(matches_df, threshold)


def _validate_partner_overlap_inputs(values: Dict[str, Any]) -> None:
    threshold = float(values.get("fuzzy_threshold", 0.8))
    if threshold < 0.5 or threshold > 1.0:
        raise ValueError("fuzzy_threshold must be between 0.5 and 1.0.")


async def build_partner_overlap(
    *,
    spreadsheet_id: Optional[str],
    inputs: Any,
    sheets_service,
    sf_client,
    match_gateway: Any = None,
    title: str = "Ecosystem Partner Overlap Finder",
) -> Dict[str, Any]:
    payload = _inputs_to_dict(inputs)
    _validate_partner_overlap_inputs(payload)

    partner_spreadsheet_id = payload.get("partner_spreadsheet_id") or spreadsheet_id
    partner_sheet_tab = payload.get("partner_sheet_tab")
    partner_range_a1 = payload.get("partner_range_a1")
    partner_header_row = int(payload.get("partner_header_row", 1))
    partner_company_col = payload.get("partner_company_col")
    partner_domain_col = payload.get("partner_domain_col")
    partner_segment_col = payload.get("partner_segment_col")

    our_customer_field = payload.get("our_customer_field")
    our_customer_values = _normalize_values(payload.get("our_customer_values"))
    our_customer_field_type = payload.get("our_customer_field_type") or "picklist"

    our_prospect_field = payload.get("our_prospect_field")
    our_prospect_values = _normalize_values(payload.get("our_prospect_values"))
    our_prospect_field_type = payload.get("our_prospect_field_type") or "picklist"

    match_domain_first = bool(payload.get("match_domain_first", True))
    match_fuzzy_name = bool(payload.get("match_fuzzy_name", True))
    fuzzy_threshold = float(payload.get("fuzzy_threshold", 0.8))
    crm_domain_field = payload.get("crm_domain_field") or "Website"

    enable_unmatched_tab = bool(payload.get("enable_unmatched_tab", True))
    crm_fields = payload.get("crm_fields")
    if isinstance(crm_fields, str):
        crm_fields = [f.strip() for f in crm_fields.split(",") if f.strip()]
    if not crm_fields:
        crm_fields = ["Id", "Name", "Website", "Industry"]

    suffix = payload.get("tab_suffix") or ""
    replace_existing = (payload.get("idempotency_action") or "") == "replace"

    if not partner_spreadsheet_id:
        raise ValueError("partner_spreadsheet_id is required.")
    if not partner_sheet_tab:
        raise ValueError("partner_sheet_tab is required.")
    if not partner_range_a1:
        raise ValueError("partner_range_a1 is required.")

    partner_tab = f"Partner_List{suffix}"
    match_tab = f"Match_Results{suffix}"
    summary_tab = f"Overlap_Summary{suffix}"
    cosell_tab = f"CoSell_Targets{suffix}"
    referral_tab = f"Referral_Targets{suffix}"
    unmatched_tab = f"Unmatched{suffix}"

    created = False
    if spreadsheet_id is None:
        spreadsheet = sheets_service.spreadsheets().create(
            body={"properties": {"title": title}}
        ).execute()
        spreadsheet_id = spreadsheet["spreadsheetId"]
        created = True

    for tab in [partner_tab, match_tab, summary_tab, cosell_tab, referral_tab]:
        _ensure_sheet(sheets_service, spreadsheet_id, tab, replace=replace_existing)
    if enable_unmatched_tab:
        _ensure_sheet(
            sheets_service, spreadsheet_id, unmatched_tab, replace=replace_existing
        )
    elif replace_existing:
        _ensure_sheet(
            sheets_service, spreadsheet_id, unmatched_tab, replace=replace_existing
        )

    escaped_tab = str(partner_sheet_tab).replace("'", "''")
    partner_range = f"'{escaped_tab}'!{partner_range_a1}"
    partner_values = (
        sheets_service.spreadsheets()
        .values()
        .get(spreadsheetId=partner_spreadsheet_id, range=partner_range)
        .execute()
        .get("values", [])
    )

    parsed = parse_a1_range(partner_range_a1)
    header_index = partner_header_row - parsed.start_row
    if header_index < 0 or header_index >= len(partner_values):
        raise ValueError("Partner header row is outside the selected range.")
    headers = partner_values[header_index]
    headers = [str(h or "").strip() for h in headers]

    header_lookup = {str(h or "").strip().lower(): idx for idx, h in enumerate(headers)}

    def _col_index(col_name: Optional[str]) -> Optional[int]:
        if not col_name:
            return None
        return header_lookup.get(str(col_name).strip().lower())

    company_idx = _col_index(partner_company_col)
    if company_idx is None:
        raise ValueError("Partner company column not found in header row.")
    domain_idx = _col_index(partner_domain_col)
    segment_idx = _col_index(partner_segment_col)

    partner_rows = []
    for row in partner_values[header_index + 1 :]:
        if not row or all(str(cell or "").strip() == "" for cell in row):
            continue
        row_values = list(row) + [""] * (len(headers) - len(row))
        company = row_values[company_idx] if company_idx is not None else ""
        domain = row_values[domain_idx] if domain_idx is not None else ""
        segment = row_values[segment_idx] if segment_idx is not None else ""
        partner_rows.append(
            {
                "raw": {headers[i]: row_values[i] for i in range(len(headers))},
                "company": company,
                "domain": domain,
                "segment": segment,
                "normalized_name": _normalize_name(company),
                "normalized_domain": _normalize_domain(domain),
            }
        )

    crm_fields_list: List[str] = []

    def _append_field(field_name: Optional[str]) -> None:
        if not field_name:
            return
        field_name = str(field_name).strip()
        if field_name and field_name not in crm_fields_list:
            crm_fields_list.append(field_name)

    for field in crm_fields:
        _append_field(field)
    _append_field("Id")
    _append_field("Name")
    _append_field(crm_domain_field)
    _append_field(our_customer_field)
    _append_field(our_prospect_field)

    customer_clause = _build_filter_clause(
        our_customer_field, our_customer_values, our_customer_field_type
    )
    customer_soql = f"SELECT {', '.join(crm_fields_list)} FROM Account WHERE {customer_clause}"
    customer_records = await _fetch_records(sf_client, customer_soql)

    prospect_records: List[Dict[str, Any]] = []
    if our_prospect_field:
        prospect_clause = _build_filter_clause(
            our_prospect_field, our_prospect_values, our_prospect_field_type
        )
        prospect_soql = (
            f"SELECT {', '.join(crm_fields_list)} FROM Account WHERE {prospect_clause}"
        )
        prospect_records = await _fetch_records(sf_client, prospect_soql)

    crm_accounts_by_id: Dict[str, Dict[str, Any]] = {}

    def _merge_records(records: List[Dict[str, Any]], flag: str) -> None:
        for record in records:
            account_id = record.get("Id")
            if not account_id:
                continue
            existing = crm_accounts_by_id.get(account_id)
            if existing:
                existing.update(record)
            else:
                existing = dict(record)
            existing.setdefault("_is_customer", False)
            existing.setdefault("_is_prospect", False)
            if flag == "customer":
                existing["_is_customer"] = True
            if flag == "prospect":
                existing["_is_prospect"] = True
            crm_accounts_by_id[account_id] = existing

    _merge_records(customer_records, "customer")
    _merge_records(prospect_records, "prospect")

    crm_accounts = []
    for record in crm_accounts_by_id.values():
        normalized_domain = _normalize_domain(record.get(crm_domain_field))
        normalized_name = _normalize_name(record.get("Name"))
        record["_normalized_domain"] = normalized_domain
        record["_normalized_name"] = normalized_name
        crm_accounts.append(record)

    domain_index: Dict[str, List[int]] = defaultdict(list)
    for idx, account in enumerate(crm_accounts):
        if account.get("_normalized_domain"):
            domain_index[account["_normalized_domain"]].append(idx)

    match_results: Dict[int, Dict[str, Any]] = {}
    matched_indices: set[int] = set()

    if match_domain_first:
        for idx, partner in enumerate(partner_rows):
            domain_key = partner.get("normalized_domain")
            if not domain_key:
                continue
            hits = domain_index.get(domain_key) or []
            if not hits:
                continue
            chosen_idx = hits[0]
            match_results[idx] = {
                "crm_index": chosen_idx,
                "score": 1.0,
                "method": "domain_exact",
            }
            matched_indices.add(idx)

    if match_fuzzy_name:
        unmatched_indices = [
            idx for idx in range(len(partner_rows)) if idx not in matched_indices
        ]
        if unmatched_indices and crm_accounts:
            partner_names = [
                partner_rows[idx]["normalized_name"] for idx in unmatched_indices
            ]
            account_names = [acct["_normalized_name"] for acct in crm_accounts]
            fuzzy_matches = await _run_fuzzy_match(
                partner_names, account_names, fuzzy_threshold, match_gateway
            )
            for source_id, (ref_id, score) in fuzzy_matches.items():
                partner_idx = unmatched_indices[source_id]
                match_results[partner_idx] = {
                    "crm_index": ref_id,
                    "score": score,
                    "method": "fuzzy_name",
                }
                matched_indices.add(partner_idx)

    match_headers = [
        "Partner Company",
        "Partner Domain",
        "CRM Account",
        "CRM Account Id",
        "Match Method",
        "Match Score",
        "Confidence",
        "Opportunity Type",
    ]
    crm_extra_fields = [f for f in crm_fields_list if f not in {"Id", "Name"}]
    match_headers.extend(crm_extra_fields)

    score_col_letter = _col_letter(match_headers.index("Match Score"))
    confidence_col_letter = _col_letter(match_headers.index("Confidence"))
    opportunity_col_letter = _col_letter(match_headers.index("Opportunity Type"))
    arr_field_name = _pick_arr_field(crm_extra_fields)
    arr_col_letter = (
        _col_letter(match_headers.index(arr_field_name)) if arr_field_name else None
    )
    confidence_threshold_cell = _sheet_cell(summary_tab, "$B$2")
    target_percent_cell = _sheet_cell(summary_tab, "$C$2")

    target_headers = match_headers + ["Target $", "Priority Score"]

    match_rows = [match_headers]
    cosell_rows = [target_headers]
    referral_rows = [target_headers]
    unmatched_rows = [
        ["Partner Company", "Partner Domain", "Partner Segment", "Normalized Company", "Normalized Domain"]
    ]

    matched_count = 0
    cosell_count = 0
    referral_count = 0

    def _confidence_formula(row_num: int) -> str:
        return (
            f"=IF({score_col_letter}{row_num}>={confidence_threshold_cell},\"High\","
            f"IF({score_col_letter}{row_num}>=50,\"Medium\",\"Low\"))"
        )

    def _target_formula(row_num: int) -> str:
        if arr_col_letter:
            return f"=IFERROR({arr_col_letter}{row_num}*{target_percent_cell},0)"
        return f"=IFERROR({score_col_letter}{row_num}*{target_percent_cell},0)"

    def _priority_formula(row_num: int) -> str:
        if arr_col_letter:
            return (
                f"=IFERROR(({score_col_letter}{row_num}/100)*0.7+"
                f"IFERROR({arr_col_letter}{row_num}/MAX({arr_col_letter}:{arr_col_letter}),0)*0.3,0)*100"
            )
        return f"=IFERROR({score_col_letter}{row_num},0)"

    for idx, partner in enumerate(partner_rows):
        match_info = match_results.get(idx)
        crm_account = crm_accounts[match_info["crm_index"]] if match_info else None
        partner_is_customer, partner_is_prospect = _classify_partner_segment(
            partner.get("segment")
        )
        our_is_customer = bool(crm_account and crm_account.get("_is_customer"))
        our_is_prospect = bool(crm_account and crm_account.get("_is_prospect"))
        opportunity = _determine_opportunity_type(
            partner_is_customer, partner_is_prospect, our_is_customer, our_is_prospect
        )

        if match_info:
            matched_count += 1
            score = float(match_info.get("score") or 0.0)
            match_row_num = len(match_rows) + 1
            match_row = [
                partner.get("company", ""),
                partner.get("domain", ""),
                crm_account.get("Name") if crm_account else "",
                crm_account.get("Id") if crm_account else "",
                match_info.get("method") or "",
                round(score * 100, 2),
                _confidence_formula(match_row_num),
                opportunity,
            ]
            for field in crm_extra_fields:
                match_row.append(crm_account.get(field, "") if crm_account else "")
            match_rows.append(match_row)
            if opportunity == "Co-sell":
                cosell_row_num = len(cosell_rows) + 1
                cosell_row = [
                    partner.get("company", ""),
                    partner.get("domain", ""),
                    crm_account.get("Name") if crm_account else "",
                    crm_account.get("Id") if crm_account else "",
                    match_info.get("method") or "",
                    round(score * 100, 2),
                    _confidence_formula(cosell_row_num),
                    opportunity,
                ]
                for field in crm_extra_fields:
                    cosell_row.append(crm_account.get(field, "") if crm_account else "")
                cosell_row.extend(
                    [_target_formula(cosell_row_num), _priority_formula(cosell_row_num)]
                )
                cosell_rows.append(cosell_row)
                cosell_count += 1
            if opportunity == "Referral":
                referral_row_num = len(referral_rows) + 1
                referral_row = [
                    partner.get("company", ""),
                    partner.get("domain", ""),
                    crm_account.get("Name") if crm_account else "",
                    crm_account.get("Id") if crm_account else "",
                    match_info.get("method") or "",
                    round(score * 100, 2),
                    _confidence_formula(referral_row_num),
                    opportunity,
                ]
                for field in crm_extra_fields:
                    referral_row.append(crm_account.get(field, "") if crm_account else "")
                referral_row.extend(
                    [_target_formula(referral_row_num), _priority_formula(referral_row_num)]
                )
                referral_rows.append(referral_row)
                referral_count += 1
        else:
            unmatched_rows.append(
                [
                    partner.get("company", ""),
                    partner.get("domain", ""),
                    partner.get("segment", ""),
                    partner.get("normalized_name", ""),
                    partner.get("normalized_domain", ""),
                ]
            )

    total_partners = len(partner_rows)
    unmatched_count = total_partners - matched_count
    match_rate = round((matched_count / total_partners) * 100, 2) if total_partners else 0

    summary_rows = [
        ["Parameters", "Confidence Threshold", "Target Match Rate", "", ""],
        ["", 80, 0.25, "", ""],
        ["Opportunity Type", "Match Count", "Match Rate %", "Avg Score", "High Confidence"],
    ]
    summary_categories = ["Co-sell", "Referral", "Overlap", "None"]
    summary_data_start = 4
    for idx, label in enumerate(summary_categories):
        row_num = summary_data_start + idx
        match_count_formula = (
            f"=COUNTIF({_quote_tab(match_tab)}!{opportunity_col_letter}:{opportunity_col_letter},"
            f"A{row_num})"
        )
        match_rate_formula = (
            f"=IFERROR(B{row_num}/COUNTA({_quote_tab(partner_tab)}!A2:A)*100,0)"
        )
        avg_score_formula = (
            f"=IFERROR(AVERAGEIF({_quote_tab(match_tab)}!{opportunity_col_letter}:{opportunity_col_letter},"
            f"A{row_num},{_quote_tab(match_tab)}!{score_col_letter}:{score_col_letter}),0)"
        )
        high_conf_formula = (
            f"=COUNTIFS({_quote_tab(match_tab)}!{opportunity_col_letter}:{opportunity_col_letter},A{row_num},"
            f"{_quote_tab(match_tab)}!{confidence_col_letter}:{confidence_col_letter},\"High\")"
        )
        summary_rows.append(
            [label, match_count_formula, match_rate_formula, avg_score_formula, high_conf_formula]
        )
    total_row_num = summary_data_start + len(summary_categories)
    total_matches_formula = f"=SUM(B{summary_data_start}:B{total_row_num - 1})"
    overall_match_rate_formula = (
        f"=IFERROR(B{total_row_num}/COUNTA({_quote_tab(partner_tab)}!A2:A)*100,0)"
    )
    total_avg_score_formula = (
        f"=IFERROR(AVERAGE({_quote_tab(match_tab)}!{score_col_letter}:{score_col_letter}),0)"
    )
    total_high_conf_formula = f"=SUM(E{summary_data_start}:E{total_row_num - 1})"
    summary_rows.append(
        [
            "TOTAL",
            total_matches_formula,
            overall_match_rate_formula,
            total_avg_score_formula,
            total_high_conf_formula,
        ]
    )

    partner_headers = headers + ["Normalized Company", "Normalized Domain"]
    partner_list_rows = [partner_headers]
    for partner in partner_rows:
        row = [partner["raw"].get(h, "") for h in headers]
        row.append(partner.get("normalized_name", ""))
        row.append(partner.get("normalized_domain", ""))
        partner_list_rows.append(row)

    _write_rows(sheets_service, spreadsheet_id, partner_tab, partner_list_rows)
    _write_rows(sheets_service, spreadsheet_id, match_tab, match_rows)
    _write_rows(sheets_service, spreadsheet_id, summary_tab, summary_rows)
    _write_rows(sheets_service, spreadsheet_id, cosell_tab, cosell_rows)
    _write_rows(sheets_service, spreadsheet_id, referral_tab, referral_rows)
    if enable_unmatched_tab:
        _write_rows(sheets_service, spreadsheet_id, unmatched_tab, unmatched_rows)

    validation_errors: List[str] = []
    if not partner_rows:
        validation_errors.append("No partner rows found in the selected range.")
    if not crm_accounts:
        validation_errors.append("No CRM accounts found for the selected filters.")

    validation = {
        "status": "issues" if validation_errors else "ok",
        "errors": validation_errors,
    }

    summary = {
        "total_partners": total_partners,
        "matched": matched_count,
        "unmatched": unmatched_count,
        "match_rate_pct": match_rate,
        "co_sell_opportunities": cosell_count,
        "referral_opportunities": referral_count,
    }

    tabs_created = [partner_tab, match_tab, summary_tab, cosell_tab, referral_tab]
    if enable_unmatched_tab:
        tabs_created.append(unmatched_tab)

    return {
        "spreadsheet_id": spreadsheet_id,
        "url": f"https://docs.google.com/spreadsheets/d/{spreadsheet_id}",
        "tabs_created": tabs_created,
        "created": created,
        "validation": validation,
        "summary": summary,
    }
