#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
简化版本：跳过登录检测，直接开始处理（适用于已登录的情况）
"""

import os
import sys

# 强制立即输出
sys.stdout.reconfigure(line_buffering=True)
sys.stderr.reconfigure(line_buffering=True)

print("="*60)
print("  MDP Termination - 跳过登录检测")
print("="*60)
print()

# 导入
print(">>> 导入模块...")
from playwright.sync_api import sync_playwright
import json
import subprocess
import time
from openpyxl import load_workbook
from datetime import datetime
import csv

print("[OK] 所有模块已导入")
print()

# 加载配置
print(">>> 加载配置...")
config_file = "config.json"
with open(config_file, "r", encoding="utf-8") as f:
    config = json.load(f)

# 兼容不同的配置文件格式
crm_url = (
    config.get('crm', {}).get('url') or
    config.get('crm_url')
)

username = sys.argv[2] if len(sys.argv) > 2 else None
if not username:
    username = (
        config.get('crm', {}).get('username') or
        config.get('crm_username')
    )

if not username:
    print("请提供 CRM 用户名")
    print("用法: python mdp_termination_auto_skip_login.py <Excel文件> <CRM_Username>")
    sys.exit(1)

# 获取 Excel 文件
excel_file = sys.argv[1] if len(sys.argv) > 1 else None
if not excel_file:
    print("请提供 Excel 文件")
    print("用法: python mdp_termination_auto_skip_login.py <Excel文件> <CRM_Username>")
    sys.exit(1)

if not os.path.exists(excel_file):
    print(f"[ERROR] Excel 文件不存在: {excel_file}")
    sys.exit(1)

print(f"[OK] 配置已加载")
print(f"  CRM URL: {crm_url}")
print(f"  用户名: {username}")
print(f"  Excel 文件: {excel_file}")
print()

# 读取 Excel 文件
print(f">>> 读取 Excel 文件: {excel_file}")
try:
    wb = load_workbook(excel_file, read_only=True)
    ws = wb.active

    # Excel 格式：
    # | Domain | EmployeeID | SamAccountName | TerminationDay | status | Backup |
    # |--------|------------|----------------|----------------|--------|--------|
    # | ...    | 172034     | ...            | ...            | ...    | ...    |

    employee_data = []  # 存储完整数据

    # 从第2行开始读取（第1行是标题）
    for row in ws.iter_rows(min_row=2, values_only=True):
        if len(row) >= 2 and row[1]:  # 确保至少有2列，且 EmployeeID 列有值
            emp_id = str(row[1]).strip()  # row[1] 是第二列（EmployeeID）
            domain = str(row[0]).strip() if row[0] else ""  # row[0] 是第一列（Domain）
            sam_account = str(row[2]).strip() if len(row) > 2 and row[2] else ""  # row[2] 是第三列（SamAccountName）

            if emp_id:
                employee_data.append({
                    'employee_id': emp_id,
                    'domain': domain,
                    'sam_account': sam_account
                })

    wb.close()

    employee_ids = [data['employee_id'] for data in employee_data]

    print(f"[OK] 找到 {len(employee_ids)} 个 EmployeeId")
    if len(employee_ids) <= 10:
        print(f"  列表: {', '.join(employee_ids)}")
    else:
        print(f"  前10个: {', '.join(employee_ids[:10])}...")

except Exception as e:
    print(f"[ERROR] 读取 Excel 失败: {e}")
    import traceback
    traceback.print_exc()
    sys.exit(1)

print()

# 全局变量
browser = None
context = None
page = None

def init_browser():
    """初始化浏览器（跳过登录检测）"""
    global browser, context, page

    print(">>> 初始化浏览器...")
    print()
    print("  [重要] 请确保浏览器已经登录 CRM！")
    print("  如果未登录，请在浏览器中手动登录后，脚本会继续执行")
    print()

    with sync_playwright() as p:
        print("  [1/2] 启动浏览器...")
        browser = p.chromium.launch(
            headless=False,
            channel="msedge",
            slow_mo=100,
            args=[
                '--incognito',
                '--disable-blink-features=AutomationControlled',
            ]
        )

        print("  [OK] 浏览器已启动")

        context = browser.new_context(
            ignore_https_errors=True,
            accept_downloads=False,
            storage_state=None,
        )

        page = context.new_page()

        print("  [2/2] 访问 CRM...")

        login_url = f"{crm_url.rstrip('/')}/MDP/"
        page.goto(login_url, wait_until="domcontentloaded", timeout=30000)
        time.sleep(3)

        current_url = page.url
        print(f"  当前 URL: {current_url}")

        # 检查是否需要登录
        if 'errorhandler.aspx' in current_url:
            print()
            print("  [WARNING] 检测到错误页面（旧会话）")
            print("  >> 请在浏览器中手动刷新或重新登录")
            print("  >> 按 Ctrl+C 继续执行，或等待 30 秒自动继续...")
            print()

            try:
                time.sleep(30)
            except KeyboardInterrupt:
                print()
                print("  [INFO] 继续执行...")
        else:
            print("  [OK] 页面已加载")

        print()
        print("="*60)
        print("  [OK] 开始处理用户...")
        print("="*60)
        print()

        # 处理所有用户
        results = []

        for idx, employee_id in enumerate(employee_ids, 1):
            print(f"\n>>> [{idx}/{len(employee_ids)}] 处理 EmployeeId: {employee_id}")
            print("-"*60)

            result = process_employee(employee_id)

            # 保存结果
            results.append(result)

            # 每处理完一个用户，暂停一下
            if idx < len(employee_ids):
                print(f"\n  等待 3 秒后处理下一个...")
                time.sleep(3)

        # 生成报告
        print()
        print("="*60)
        print("  所有用户处理完成！生成报告...")
        print("="*60)
        print()

        generate_report(results)

        print()
        print("浏览器将在 30 秒后关闭...")
        time.sleep(30)

        context.close()
        browser.close()

def query_ad(employee_id):
    """查询 AD 获取 DisplayName"""
    try:
        ps_command = [
            "powershell",
            "-Command",
            f"Import-Module ActiveDirectory; Get-ADUser -Filter \"EmployeeId -eq '{employee_id}'\" -Properties DisplayName, SamAccountName | ConvertTo-Json"
        ]

        result = subprocess.run(
            ps_command,
            capture_output=True,
            text=True,
            timeout=30,
            encoding='utf-8'
        )

        if result.stderr and "Cannot find" in result.stderr:
            return None, "用户不存在"

        if not result.stdout.strip():
            return None, "用户不存在"

        user_data = json.loads(result.stdout)

        if not user_data or not isinstance(user_data, dict):
            return None, "用户不存在"

        display_name = user_data.get('DisplayName')
        sAMAccountName = user_data.get('SamAccountName')

        # 移除 -d 后缀（如果存在）
        if display_name and display_name.endswith('-d'):
            display_name_without_d = display_name[:-2].strip()
            print(f"  [INFO] AD DisplayName: {display_name}")
            print(f"  [INFO] 尝试使用不含 -d 的名称: {display_name_without_d}")
            return display_name_without_d, None

        return display_name, None

    except Exception as e:
        return None, f"AD 查询失败: {str(e)}"

def search_user_in_crm(display_name):
    """在 CRM 中搜索用户"""
    try:
        print(f"  [1/3] 在 CRM 中搜索: {display_name}")

        # 构造搜索 URL
        search_url = f"{crm_url.rstrip('/')}/MDP/multientityquickfind/multientityquickfind.aspx"
        params = f"?text={display_name}&option=0&pagemode=iframe"

        full_url = search_url + params
        print(f"  URL: {full_url}")

        page.goto(full_url, wait_until="domcontentloaded", timeout=30000)

        # 重试机制：等待页面加载并查找元素
        print(f"  等待搜索结果加载...")

        max_retries = 5
        card_clicked = False

        for retry in range(max_retries):
            if retry > 0:
                print(f"  [重试 {retry}/{max_retries-1}] 等待页面加载...")

            # 每次重试等待更长时间
            wait_time = 3 + retry * 2  # 第一次 3 秒，然后 5, 7, 9, 11 秒
            print(f"  等待 {wait_time} 秒...")
            time.sleep(wait_time)

            current_url = page.url
            print(f"  当前 URL: {current_url}")

            # 检查是否有搜索结果
            page_content = page.content()

            # 检查是否找到用户
            if display_name.lower() not in page_content.lower():
                print(f"  [INFO] 未在页面中找到用户名，继续等待...")
                continue

            print(f"  [OK] 找到用户: {display_name}")

            # 尝试查找用户卡片并点击
            print(f"  尝试点击用户卡片...")

            # 方法 1: 查找 id="attribone" 的元素
            try:
                elements = page.query_selector_all('span#attribone')
                print(f"  找到 {len(elements)} 个 attribone 元素")

                for elem in elements:
                    text = elem.inner_text() or ""
                    print(f"  检查元素: '{text}'")

                    if display_name.lower() in text.lower():
                        print(f"  匹配！点击用户卡片...")
                        elem.click(timeout=5000)
                        time.sleep(2)
                        card_clicked = True
                        print(f"  [OK] 已点击用户卡片")
                        break

                if card_clicked:
                    break
            except Exception as e:
                print(f"  方法1失败: {e}")

            # 方法 2: 尝试其他选择器
            if not card_clicked:
                print(f"  尝试其他选择器...")
                try:
                    # 尝试通过文本查找
                    element = page.get_by_text(display_name, exact=False).first
                    if element:
                        print(f"  通过文本找到元素，点击...")
                        element.click(timeout=5000)
                        time.sleep(2)
                        card_clicked = True
                        print(f"  [OK] 已点击用户卡片")
                        break
                except Exception as e:
                    print(f"  方法2失败: {e}")

            if card_clicked:
                break

        if card_clicked:
            return True, "找到用户并点击"
        else:
            print(f"  [WARNING] 无法自动点击卡片")
            print(f"  [INFO] 请在浏览器中手动点击用户: {display_name}")
            print(f"  等待 10 秒供你手动操作...")
            time.sleep(10)
            return True, "找到用户（手动点击）"

    except Exception as e:
        import traceback
        return False, f"搜索失败: {str(e)}"

def disable_user_in_crm():
    """在 CRM 中禁用当前用户"""
    try:
        print(f"  [2/3] 执行 Disable 操作...")

        # 等待页面加载（点击用户卡片后）
        # 需要更长的等待时间，因为页面可能需要完全加载
        print(f"  等待用户详情页面加载...")
        print(f"  等待 5 秒...")
        time.sleep(5)  # 增加到 5 秒

        print(f"  开始查找 Disable 按钮...")

        # 调试：显示页面上所有的按钮和链接
        try:
            print(f"  [调试] 列出页面上所有的 a 标签...")
            all_links = page.query_selector_all('a')
            print(f"  找到 {len(all_links)} 个 <a> 标签")

            # 显示前 10 个包含 Disable 的链接
            disable_count = 0
            for link in all_links:
                text = link.inner_text() or ""
                aria_label = link.get_attribute('aria-label') or ""
                class_name = link.get_attribute('class') or ""

                if 'disable' in text.lower() or 'disable' in aria_label.lower() or 'ms-crm-Menu-Label' in class_name:
                    disable_count += 1
                    if disable_count <= 10:
                        print(f"    - 文本: '{text[:50]}'")
                        print(f"      aria-label: '{aria_label[:50]}'")
                        print(f"      class: '{class_name[:50]}'")

            print(f"  共找到 {disable_count} 个包含 'Disable' 的链接")
        except Exception as e:
            print(f"  [调试] 无法列出链接: {e}")

        # 重试机制：查找 Disable 按钮
        max_retries = 5
        button_clicked = False

        for retry in range(max_retries):
            if retry > 0:
                print(f"  [重试 {retry}/{max_retries-1}] 查找 Disable 按钮...")

            # 每次重试等待时间更长
            wait_time = 3 + retry * 3  # 3, 6, 9, 12, 15 秒
            print(f"  等待 {wait_time} 秒...")
            time.sleep(wait_time)

            # 方法 1: 使用 command 属性（最准确）
            try:
                selector = 'span[command="systemuser|NoRelationship|Form|Mscrm.Form.systemuser.Disable"]'
                if page.is_visible(selector, timeout=2000):
                    print(f"  找到 Disable 按钮 (方法1: command属性)")
                    page.click(selector, timeout=5000)
                    time.sleep(2)
                    button_clicked = True
                    print(f"  [OK] 已点击 Disable 按钮")
                    break
            except:
                pass

            # 方法 2: 使用部分 command 属性
            if not button_clicked:
                try:
                    selector = 'span[command*="Disable"]'
                    elements = page.query_selector_all(selector)
                    print(f"  找到 {len(elements)} 个包含 'Disable' 的 command 元素")

                    for elem in elements:
                        command = elem.get_attribute('command') or ""
                        if 'systemuser' in command and 'Disable' in command:
                            print(f"  找到 Disable 按钮 (方法2: 部分command属性)")
                            elem.click(timeout=5000)
                            time.sleep(2)
                            button_clicked = True
                            print(f"  [OK] 已点击 Disable 按钮")
                            break

                    if button_clicked:
                        break
                except Exception as e:
                    print(f"  方法2失败: {e}")

            # 方法 3: 使用文本内容
            if not button_clicked:
                try:
                    element = page.get_by_text("Disable", exact=True).first
                    if element and element.is_visible():
                        print(f"  找到 Disable 按钮 (方法3: 文本内容)")
                        element.click(timeout=5000)
                        time.sleep(2)
                        button_clicked = True
                        print(f"  [OK] 已点击 Disable 按钮")
                        break
                except Exception as e:
                    print(f"  方法3失败: {e}")

            # 方法 4: 使用 XPath（用户提供的）
            if not button_clicked:
                try:
                    # 尝试用户提供的 XPath
                    xpath_selector = '//*[@id="systemuser|NoRelationship|Form|Mscrm.Form.systemuser.Disable"]/span/a'
                    print(f"  尝试 XPath: {xpath_selector}")

                    # Playwright 使用 xpath= 前缀
                    element = page.locator(f'xpath={xpath_selector}').first
                    if element.is_visible():
                        print(f"  找到 Disable 按钮 (方法4: XPath)")
                        element.click(timeout=5000)
                        time.sleep(2)
                        button_clicked = True
                        print(f"  [OK] 已点击 Disable 按钮")
                        break
                except Exception as e:
                    print(f"  方法4失败: {e}")

            # 方法 5: 直接查找 <a> 标签
            if not button_clicked:
                try:
                    # 查找包含 "Disable" 文本的 <a> 标签
                    elements = page.query_selector_all('a.ms-crm-Menu-Label')
                    print(f"  找到 {len(elements)} 个 ms-crm-Menu-Label 元素")

                    for elem in elements:
                        text = elem.inner_text() or ""
                        aria_label = elem.get_attribute('aria-label') or ""

                        if 'Disable' in text or 'Disable' in aria_label:
                            print(f"  找到 Disable 按钮 (方法5: <a>标签)")
                            print(f"    文本: '{text}'")
                            print(f"    aria-label: '{aria_label}'")

                            # 尝试滚动到元素
                            elem.scroll_into_view_if_needed()
                            time.sleep(1)

                            elem.click(timeout=5000)
                            time.sleep(2)
                            button_clicked = True
                            print(f"  [OK] 已点击 Disable 按钮")
                            break

                    if button_clicked:
                        break
                except Exception as e:
                    print(f"  方法5失败: {e}")

            # 方法 6: 使用 aria-label 精确匹配
            if not button_clicked:
                try:
                    selector = 'a[aria-label*="Disable"]'
                    if page.is_visible(selector, timeout=2000):
                        print(f"  找到 Disable 按钮 (方法6: aria-label)")
                        page.click(selector, timeout=5000)
                        time.sleep(2)
                        button_clicked = True
                        print(f"  [OK] 已点击 Disable 按钮")
                        break
                except Exception as e:
                    print(f"  方法6失败: {e}")

            if button_clicked:
                break

        if not button_clicked:
            print(f"  [WARNING] 未找到 Disable 按钮")
            print(f"  [INFO] 请在浏览器中手动点击 Disable 按钮")
            print(f"  等待 15 秒...")
            time.sleep(15)
            return False, "未找到 Disable 按钮（需手动操作）"

        # 检查是否有确认对话框
        print(f"  [3/3] 确认 Disable 操作...")

        # 等待可能的确认对话框
        time.sleep(2)

        # 尝试查找确认按钮（重试机制）
        confirm_clicked = False

        for retry in range(3):
            if retry > 0:
                print(f"  重试查找确认对话框 {retry}/2...")
                time.sleep(2)

            # 检查是否有确认对话框
            confirm_selectors = [
                'button:has-text("OK")',
                'button:has-text("Yes")',
                'button:has-text("Confirm")',
                'input[type="button"][value="OK"]',
                'input[type="button"][value="Yes"]',
                '[role="button"][aria-label*="OK"]',
                '[role="button"][aria-label*="Yes"]',
            ]

            for selector in confirm_selectors:
                try:
                    if page.is_visible(selector, timeout=1000):
                        print(f"  找到确认按钮: {selector}")
                        page.click(selector, timeout=5000)
                        time.sleep(2)
                        confirm_clicked = True
                        print(f"  [OK] 已确认 Disable")
                        break
                except:
                    continue

            if confirm_clicked:
                break

        if not confirm_clicked:
            print(f"  [INFO] 未检测到确认对话框，可能已直接完成")

        # 等待操作完成
        time.sleep(2)

        return True, "Disable 成功"

    except Exception as e:
        import traceback
        print(f"  [ERROR] Disable 失败: {e}")
        import traceback
        traceback.print_exc()
        return False, f"Disable 失败: {str(e)}"

def process_employee(employee_id):
    """处理单个用户"""
    result = {
        'employee_id': employee_id,
        'display_name': '',
        'ad_account': '',
        'status': 'pending',
        'message': '',
        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    }

    try:
        # 1. 查询 AD
        print(f"  步骤 1: 查询 AD")
        display_name, error = query_ad(employee_id)

        if error:
            print(f"  [ERROR] {error}")
            result['status'] = 'failed'
            result['message'] = error
            return result

        print(f"  [OK] DisplayName: {display_name}")
        result['display_name'] = display_name

        # 2. 在 CRM 中搜索用户
        print(f"  步骤 2: 在 CRM 中搜索用户")
        found, message = search_user_in_crm(display_name)

        if not found:
            print(f"  [ERROR] {message}")
            result['status'] = 'failed'
            result['message'] = message
            return result

        # 3. Disable 用户
        print(f"  步骤 3: Disable 用户")
        success, message = disable_user_in_crm()

        if success:
            print(f"  [OK] {message}")
            result['status'] = 'success'
            result['message'] = message
        else:
            print(f"  [WARNING] {message}")
            result['status'] = 'partial'
            result['message'] = message

    except Exception as e:
        import traceback
        print(f"  [ERROR] 处理失败: {e}")
        result['status'] = 'failed'
        result['message'] = f"异常: {str(e)}"

    return result

def generate_report(results):
    """生成 CSV 报告"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    report_file = f"Termination_Report_{timestamp}.csv"

    # 写入 CSV
    with open(report_file, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)

        # 写入标题
        writer.writerow(['EmployeeId', 'DisplayName', 'Status', 'Message', 'Timestamp'])

        # 写入数据
        for result in results:
            writer.writerow([
                result['employee_id'],
                result['display_name'],
                result['status'],
                result['message'],
                result['timestamp']
            ])

    print(f"[OK] 报告已生成: {report_file}")

    # 统计
    total = len(results)
    success = sum(1 for r in results if r['status'] == 'success')
    partial = sum(1 for r in results if r['status'] == 'partial')
    failed = sum(1 for r in results if r['status'] == 'failed')

    print()
    print("统计:")
    print(f"  总数: {total}")
    print(f"  成功: {success}")
    print(f"  部分: {partial}")
    print(f"  失败: {failed}")

    # 显示失败的用户
    if failed > 0:
        print()
        print("失败的用户:")
        for r in results:
            if r['status'] == 'failed':
                print(f"  - {r['employee_id']} ({r.get('display_name', 'N/A')}): {r['message']}")

    # 显示部分成功的用户
    if partial > 0:
        print()
        print("部分成功的用户（需手动检查）:")
        for r in results:
            if r['status'] == 'partial':
                print(f"  - {r['employee_id']} ({r.get('display_name', 'N/A')}): {r['message']}")

# 主程序
if __name__ == "__main__":
    try:
        init_browser()
    except KeyboardInterrupt:
        print("\n[INFO] 用户中断")
        if browser:
            try:
                browser.close()
            except:
                pass
    except Exception as e:
        print(f"\n[ERROR] 错误: {e}")
        import traceback
        traceback.print_exc()
        if browser:
            try:
                browser.close()
            except:
                pass

    print()
    print("="*60)
    print("  程序结束")
    print("="*60)
    print()
    print("按回车退出...")
    input()
