#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""线上（CDN）验收「课题组经营」Tab。含腾讯云风险提醒页绕过。"""
import io
import json
import sys
from datetime import datetime

from playwright.sync_api import sync_playwright

CDN = 'https://bier-sales-d0gatbvlx288724e9-1458438710.tcloudbaseapp.com/workbench/index.html'
GD = json.load(io.open('/Users/liuxinyuan/Desktop/Hermes输出-工作类/数据/ls_groups.json', encoding='utf-8'))
K = GD['kpi']
OK = True


def chk(label, cond, detail=''):
    global OK
    print('  %s %-44s %s' % ('✅' if cond else '❌', label, detail))
    if not cond:
        OK = False


def expect(name):
    gs = [g for g in GD['groups'] if (g.get('orders') or 0) > 0]
    if name:
        gs = [g for g in gs if g.get('sales') == name]
    asof = datetime.strptime(K['as_of'], '%Y-%m-%d')
    paid = [float(g['amt']) for g in gs if float(g.get('amt') or 0) > 0]
    amt = sum(float(g.get('amt') or 0) for g in gs)
    y25 = sum(float(g.get('amt_p25') or 0) for g in gs)
    y26 = sum(float(g.get('amt_p26') or 0) for g in gs)
    slp = [g for g in gs if g.get('last_any') and (asof - datetime.strptime(g['last_any'], '%Y-%m-%d')).days > K['sleep']['days']]
    return {'conv': 100 * len(paid) / len(gs), 'paid': len(paid), 'all': len(gs), 'amt': amt, 'sleep': len(slp),
            'rep': sum(1 for g in gs if (g.get('orders_paid') or 0) >= 2),
            'yoy': 100 * (y26 - y25) / y25 if y25 else None}


with sync_playwright() as p:
    br = p.chromium.launch(channel='chrome', headless=True)
    pg = br.new_page(viewport={'width': 1500, 'height': 1100})
    errs = []
    pg.on('pageerror', lambda e: errs.append(str(e)))

    pg.goto(CDN, wait_until='load')
    pg.wait_for_timeout(1200)
    if '风险提醒' in pg.title():
        for _ in range(4):
            try:
                pg.click('text=确定访问', timeout=3000)
            except Exception:
                pass
            pg.wait_for_timeout(1500)
            if '风险提醒' not in pg.title():
                break
    chk('拿到真页面', '风险提醒' not in pg.title(), pg.title())

    def boot(name, role, line):
        pg.evaluate("""async (p) => {
            document.getElementById('loginOverlay').style.display='none';
            document.getElementById('app').style.display='block';
            state.user = {name:p.name, role:p.role, dept:'销售管理', line:p.line};
            state.currentLine = p.line;
            var d = await fetch('../数据/ls_groups.json?v='+Date.now(), {cache:'no-store'}).then(r=>r.json());
            state.data = state.data || {}; state.data.lsGroups = d;
            try { if (typeof renderNav === 'function') renderNav(); } catch(e) {}
            state.tab = 'lsKpi'; render();
        }""", {'name': name, 'role': role, 'line': line})
        pg.wait_for_timeout(900)

    def cards():
        return pg.evaluate("() => { var o={}; document.querySelectorAll('.stat-card').forEach(function(c){"
                           "o[c.querySelector('.label').innerText.trim()]=c.querySelector('.value').innerText.trim();}); return o; }")

    print('① 线上 LS 专属隔离')
    boot('刘新元', 'admin', 'da')
    chk('da 线无该 Tab', '课题组经营' not in pg.evaluate("() => document.querySelector('#sidebar').innerText"))
    boot('刘新元', 'admin', 'ls')
    chk('ls 线有该 Tab', '课题组经营' in pg.evaluate("() => document.querySelector('#sidebar').innerText"))

    print('② 线上管理员 KPI == 权威 JSON')
    e = expect(None)
    c = cards()
    print('    线上卡片：', c)
    chk('转化率 %.2f%%' % e['conv'], c.get('🎯 测试→成交转化率', '').startswith('%.2f' % e['conv']))
    chk('沉睡 %d' % e['sleep'], c.get('😴 沉睡课题组') == str(e['sleep']))
    chk('成交额 %.2f万' % (e['amt'] / 1e4), c.get('💵 累计成交额', '').startswith('%.2f' % (e['amt'] / 1e4)))
    chk('复购 %d' % e['rep'], c.get('🔁 复购课题组') == str(e['rep']))
    chk('单组产出 ¥%s' % format(round(e['amt'] / e['paid']), ','),
        c.get('📦 单组产出') == '¥' + format(round(e['amt'] / e['paid']), ','), c.get('📦 单组产出'))
    txt = pg.evaluate("() => document.querySelector('main').innerText")
    chk('同比 %+.1f%%' % e['yoy'], ('%+.1f%%' % e['yoy']) in txt)
    chk('含「同期」口径说明', '同期' in txt)
    chk('沉睡清单渲染', pg.evaluate("() => document.querySelectorAll('.data-table tbody tr').length") == min(20, e['sleep']))
    chk('表头为「客户数」', '客户数' in pg.evaluate("() => document.querySelector('.data-table thead').innerText"))
    pg.screenshot(path='/tmp/ls_kpi_live.png', full_page=True)

    print('③ 线上销售隔离（黄建华）')
    boot('黄建华', 'sales', 'ls')
    e2 = expect('黄建华')
    c2 = cards()
    print('    黄建华期望：%.2f%% ｜ %.2f万 ｜ 复购 %d' % (e2['conv'], e2['amt'] / 1e4, e2['rep']))
    chk('按本人复算 %.2f%%' % e2['conv'], c2.get('🎯 测试→成交转化率', '').startswith('%.2f' % e2['conv']))
    chk('按本人成交额 %.2f万' % (e2['amt'] / 1e4), c2.get('💵 累计成交额', '').startswith('%.2f' % (e2['amt'] / 1e4)))
    chk('≠ 全量（隔离生效）', abs(e2['amt'] - e['amt']) > 1)
    chk('0 JS 错误', len(errs) == 0, str(errs[:2]))
    br.close()

print('\n%s' % ('✅ 线上全部通过' if OK else '❌ 有失败项'))
sys.exit(0 if OK else 1)
