#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""2026 满意度问卷：全量核心统计（供核对/重写报告用）。

口径：主口径 = 答卷状态「质控通过」(n=470)；扩展口径 = 质控通过 + 超时但有调研意义 (n=590)。
多选按「非空即选中」计数；量表按数值。
"""
import json
import os
import re

import pandas as pd

P = ('/Users/liuxinyuan/.hermes/profiles/zone-b/cache/documents/'
     'doc_3f5eafe34e61_宝锐生物客户满意度调查问卷-2026（按选项文本）-全部.xlsx')
OUT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/数据/survey2026_stats.json'

d = pd.read_excel(P, sheet_name='答卷数据')
C = list(d.columns)


def col(i):
    return C[i] if i < len(C) else None


def series(i):
    return pd.to_numeric(d[col(i)], errors='coerce')


def sel(df, i):
    """多选列：非空即选中。"""
    c = col(i)
    if c is None:
        return df[c] if c else None
    return df[c].notna() & (df[c].astype(str).str.strip() != '')


def dist(s, name):
    v = s.dropna()
    if v.empty:
        return {}
    return {'n': int(v.count()), 'mean': round(float(v.mean()), 2), 'median': float(v.median()),
            'sd': round(float(v.std()), 2), 'pct10': round(100.0 * (v == 10).sum() / v.count(), 1),
            'pct_ge9': round(100.0 * (v >= 9).sum() / v.count(), 1),
            'pct_le6': round(100.0 * (v <= 6).sum() / v.count(), 1),
            '分布': {str(int(k)): int(vv) for k, vv in v.value_counts().sort_index().items()}}


main = d[d['答卷状态'].astype(str).str.contains('质控通过', na=False)]
ext = d[d['答卷状态'].astype(str).str.contains('质控通过|有调研意义', na=False, regex=True)]

res = {'生成时间': pd.Timestamp.now().strftime('%Y-%m-%d %H:%M'),
       '总行数': int(len(d)),
       '答卷状态': {str(k): int(v) for k, v in d['答卷状态'].value_counts(dropna=False).items()},
       '主口径 n': int(len(main)), '扩展口径 n': int(len(ext))}

# 量表题
for i, nm in ((13, 'Q1产品质量'), (14, 'Q2销售服务'), (23, 'Q4技术支持')):
    res[nm + '_主口径'] = dist(series(i)[main.index], nm)
    res[nm + '_扩展口径'] = dist(series(i)[ext.index], nm)

# 单选/多选（按选项文本）
def opt_counts(i, df, topn=None):
    s = df[col(i)].dropna().astype(str).str.strip()
    s = s[s != '']
    c = s.value_counts()
    if topn:
        c = c.head(topn)
    return {str(k): int(v) for k, v in c.items()}


res['Q6使用时长_主'] = opt_counts(32, main)
res['Q9价格评价_主'] = opt_counts(48, main)
res['Q10偏高幅度_主'] = opt_counts(50, main)
res['Q17_tNGS领域_主'] = opt_counts(91, main)
res['Q20冻干销量预期_主'] = opt_counts(107, main)

# 多选题（列名里含关键词）
def multi_by_keyword(kw, df, label_map=None, topn=None):
    out = {}
    for i, c in enumerate(C):
        if kw in str(c) and '【多选题】' in str(c):
            label = str(c).split('-')[-1].replace('【多选题】', '')
            out[label] = int(sel(df, i).sum())
    items = sorted(out.items(), key=lambda x: -x[1])
    return dict(items[:topn] if topn else items)


res['Q3销售改进_主'] = multi_by_keyword('3.您认为我们销售环节', main)
res['Q5技术改进_主'] = multi_by_keyword('5.您认为我们技术支持', main)
res['Q7选择原因_主'] = multi_by_keyword('7.您选择我们产品', main)
res['Q8了解渠道_主'] = multi_by_keyword('8.您从何处了解', main)
res['Q11最满意_主'] = multi_by_keyword('11.', main)
res['Q12最不满意_主'] = multi_by_keyword('12.您对我们产品/服务最不满意', main)
res['Q13供应商_主'] = multi_by_keyword('13.您现在采用的主要原料供应商', main)
res['Q16热点项目_主'] = multi_by_keyword('16.请选择您感兴趣', main)
res['Q18_tNGS关注_主'] = multi_by_keyword('18.在选择靶向', main)
res['Q19建库关注_主'] = multi_by_keyword('19.在使用基因组建库', main)

# 供应商占比（以主口径为分母）
vend = {}
for i, c in enumerate(C):
    if '13.您现在采用的主要原料供应商' in str(c):
        vend[str(c).split('-')[-1].replace('【多选题】', '')] = round(100.0 * sel(main, i).sum() / len(main), 1)
res['Q13渗透率_主_pct'] = dict(sorted(vend.items(), key=lambda x: -x[1]))

json.dump(res, open(OUT, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)

print('=== 口径 ===')
print('  总行 %d ｜ 主口径(质控通过) %d ｜ 扩展口径 %d' % (len(d), len(main), len(ext)))
print('  答卷状态:', res['答卷状态'])
print()
print('=== 三项评分（主口径 / 扩展口径）===')
for nm in ('Q1产品质量', 'Q2销售服务', 'Q4技术支持'):
    a, b = res[nm + '_主口径'], res[nm + '_扩展口径']
    print('  %-10s 主: 均分 %.2f (n=%d, 10分占比 %.1f%%, ≤6分 %.1f%%) ｜ 扩展: 均分 %.2f (n=%d)' % (
        nm, a['mean'], a['n'], a['pct10'], a['pct_le6'], b['mean'], b['n']))
print()
print('=== 价格评价（主口径）===')
for k, v in res['Q9价格评价_主'].items():
    print('   %-8s %4d (%.1f%%)' % (k, v, 100.0 * v / len(main)))
print('   偏高幅度:', res['Q10偏高幅度_主'])
print()
print('=== 供应商渗透率（主口径，分母 %d）===' % len(main))
for k, v in res['Q13渗透率_主_pct'].items():
    print('   %-42s %.1f%%' % (k[:42], v))
print()
print('=== 最不满意 TOP（主口径）===')
for k, v in list(res['Q12最不满意_主'].items())[:8]:
    print('   %-16s %4d (%.1f%%)' % (k, v, 100.0 * v / len(main)))
print()
print('=== 销售/技术改进需求 TOP5（主口径）===')
for k, v in list(res['Q3销售改进_主'].items())[:5]:
    print('   [销售] %-22s %4d (%.1f%%)' % (k, v, 100.0 * v / len(main)))
for k, v in list(res['Q5技术改进_主'].items())[:5]:
    print('   [技术] %-22s %4d (%.1f%%)' % (k, v, 100.0 * v / len(main)))
print()
print('→ 已落盘', OUT)
