"""
爬取黄色标记项目的成果产出 - 简化版
"""
import asyncio
import openpyxl
import re
import json
from urllib.parse import quote
from pathlib import Path
from playwright.async_api import async_playwright


def is_yellow(cell):
    fill = cell.fill
    if fill.fill_type == 'solid' and fill.fgColor:
        color = fill.fgColor
        if color.type == 'rgb' and color.rgb:
            rgb = color.rgb
            if len(rgb) >= 6:
                if len(rgb) == 8:
                    r, g, b = int(rgb[2:4], 16), int(rgb[4:6], 16), int(rgb[6:8], 16)
                else:
                    r, g, b = int(rgb[0:2], 16), int(rgb[2:4], 16), int(rgb[4:6], 16)
                if r > 200 and g > 200 and b < 100:
                    return True
    return False


def get_yellow_projects(filepath):
    wb = openpyxl.load_workbook(filepath)
    ws = wb.active
    projects = []
    for row_idx in range(2, ws.max_row + 1):
        for col_idx in range(1, ws.max_column + 1):
            if is_yellow(ws.cell(row=row_idx, column=col_idx)):
                projects.append({
                    'row': row_idx,
                    'name': ws.cell(row=row_idx, column=2).value,
                    'leader': ws.cell(row=row_idx, column=3).value,
                })
                break
    return projects


async def main():
    filepath = r'd:\OneDrive\WORK\工作\项目申请\国自然申请\tools\scraper\output\nsfc_合并_风险相关的_20260203.xlsx'
    cache_file = Path(filepath).parent / 'pub_cache.json'
    
    # 加载缓存
    cache = {}
    if cache_file.exists():
        cache = json.loads(cache_file.read_text(encoding='utf-8'))
    
    projects = get_yellow_projects(filepath)
    print(f"共 {len(projects)} 个项目，已缓存 {len(cache)} 个")
    print("启动浏览器...")
    
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        print("浏览器已启动")
        
        for i, proj in enumerate(projects):
            row_key = str(proj['row'])
            if row_key in cache:
                print(f"[{i+1}/{len(projects)}] 跳过(已缓存): {proj['name'][:25]}")
                continue
            
            print(f"[{i+1}/{len(projects)}] 处理: {proj['name'][:25]}...")
            
            try:
                # 搜索
                await page.goto(f"https://kd.nsfc.cn/finalSearchList?s={quote(proj['leader'])}")
                await asyncio.sleep(1.5)
                await page.click('button:has-text("检索")')
                await asyncio.sleep(2.5)
                
                body = await page.inner_text('body')
                short_name = proj['name'][:10]
                
                if '根据条件检索到0项' in body or short_name not in body:
                    print(f"  ✗ 未找到")
                    continue
                
                # 点击获取detail_id
                ctx = browser.contexts[0]
                new_pages = []
                ctx.on('page', lambda p: new_pages.append(p))
                
                await page.click(f'p:has-text("{short_name}")', timeout=5000)
                await asyncio.sleep(2)
                
                if not new_pages:
                    print(f"  ✗ 无法打开详情页")
                    continue
                
                url = new_pages[0].url
                match = re.search(r'id=([a-f0-9]+)', url)
                if not match:
                    await new_pages[0].close()
                    print(f"  ✗ 无法获取ID")
                    continue
                
                detail_id = match.group(1)
                
                # 获取成果
                await new_pages[0].goto(f"https://kd.nsfc.cn/finalDetails?id={detail_id}")
                await asyncio.sleep(2.5)
                detail_body = await new_pages[0].inner_text('body')
                await new_pages[0].close()
                
                paper = re.search(r'期刊论文数量\s*\n?\s*(\d+)', detail_body)
                conf = re.search(r'会议论文数量\s*\n?\s*(\d+)', detail_body)
                
                pubs = []
                if '抱歉，无成果产出' not in detail_body:
                    output = re.search(r'成果产出([\s\S]*?)(?=科研影响分析|$)', detail_body)
                    if output:
                        for m in re.finditer(r'(\d+)\.([^\n]+)\n+类型[：:]\s*([^作]+)作者[：:]\s*([^\n\d]+)', output.group(1)):
                            pubs.append({
                                'title': m.group(2).strip(),
                                'type': m.group(3).strip(),
                                'authors': m.group(4).strip()
                            })
                
                cache[row_key] = {
                    'paper_count': int(paper.group(1)) if paper else 0,
                    'conf_count': int(conf.group(1)) if conf else 0,
                    'publications': pubs
                }
                
                # 保存缓存
                cache_file.write_text(json.dumps(cache, ensure_ascii=False, indent=2), encoding='utf-8')
                print(f"  ✓ 期刊{cache[row_key]['paper_count']}, 会议{cache[row_key]['conf_count']}, 成果{len(pubs)}条")
                
            except Exception as e:
                print(f"  ✗ 错误: {e}")
            
            await asyncio.sleep(0.5)
        
        await browser.close()
    
    print(f"\n=== 完成 ===")
    print(f"成功获取 {len(cache)} 个项目")


if __name__ == "__main__":
    asyncio.run(main())
