#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MDP Termination Tool - 同步版本
使用同步 Playwright（更简单、更稳定）
"""

import os
import sys
import json
import time
import subprocess
import csv
import logging
from datetime import datetime
from pathlib import Path

try:
    from playwright.sync_api import sync_playwright
except ImportError:
    print("错误: Playwright 未安装")
    print("请运行: pip install playwright")
    sys.exit(1)

try:
    import openpyxl
    from openpyxl import load_workbook
except ImportError:
    print("错误: openpyxl 未安装")
    print("请运行: pip install openpyxl")
    sys.exit(1)

# 配置日志
log_file = f"mdp_termination_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
file_handler = logging.FileHandler(log_file, encoding='utf-8')
console_handler = logging.StreamHandler()

logging.basicConfig(
    level=logging.INFO,
    format='[%(asctime)s] [%(levelname)s] %(message)s',
    datefmt='%H:%M:%S',
    handlers=[file_handler, console_handler]
)
logger = logging.getLogger(__name__)


class PasswordManager:
    """密码管理"""

    @staticmethod
    def decrypt_password(password_file: str) -> str:
        """解密密码"""
        try:
            import dpapi
            with open(password_file, 'rb') as f:
                encrypted_bytes = f.read()
            decrypted_bytes = dpapi.decrypt(encrypted_bytes)
            return decrypted_bytes.decode('utf-8')
        except ImportError:
            # 使用 ctypes
            import ctypes
            from ctypes import wintypes

            crypt32 = ctypes.windll.crypt32

            class DATA_BLOB(ctypes.Structure):
                _fields_ = [
                    ("cbData", wintypes.DWORD),
                    ("pbData", ctypes.POINTER(ctypes.c_byte))
                ]

            with open(password_file, 'rb') as f:
                encrypted_bytes = f.read()

            buffer_type = ctypes.c_byte * len(encrypted_bytes)
            buffer = buffer_type.from_buffer_copy(encrypted_bytes)

            input_blob = DATA_BLOB()
            input_blob.cbData = len(encrypted_bytes)
            input_blob.pbData = buffer

            output_blob = DATA_BLOB()

            result = crypt32.CryptUnprotectData(
                ctypes.byref(input_blob),
                None,
                None,
                None,
                None,
                0
            )

            if not result:
                raise ValueError("DPAPI 解密失败")

            decrypted_buffer = (ctypes.c_byte * output_blob.cbData)()
            ctypes.memmove(decrypted_buffer, output_blob.pbData, output_blob.cbData)
            decrypted_bytes = bytes(decrypted_buffer)

            ctypes.windll.kernel32.LocalFree(output_blob.pbData)

            return decrypted_bytes.decode('utf-8')


def login_to_crm(url: str, username: str, password: str):
    """
    同步版本的 CRM 登录
    """
    logger.info("启动浏览器...")

    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=False,      # 显示窗口
            slow_mo=100,         # 慢速模式，更稳定
            channel="chrome"     # 使用系统 Chrome
        )

        logger.success("✓ 浏览器已启动")

        context = browser.new_context()
        page = context.new_page()

        try:
            login_url = f"{url.rstrip('/')}/MDP/"
            logger.info(f"访问: {login_url}")
            page.goto(login_url)
            logger.info("✓ 页面已加载")

            time.sleep(2)

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

            if 'main.aspx' not in current_url:
                logger.info("需要登录...")

                # 填写用户名
                logger.info("填写用户名...")
                username_filled = False
                for selector in ['input[name="username"]', 'input[type="text"]']:
                    try:
                        page.fill(selector, username, timeout=2000)
                        username_filled = True
                        logger.success(f"✓ 用户名已填写: {username}")
                        break
                    except:
                        continue

                if not username_filled:
                    raise Exception("无法找到用户名输入框")

                time.sleep(0.5)

                # 填写密码
                logger.info("填写密码...")
                password_filled = False
                for selector in ['input[name="password"]', 'input[type="password"]']:
                    try:
                        page.fill(selector, password, timeout=2000)
                        password_filled = True
                        logger.success("✓ 密码已填写")
                        break
                    except:
                        continue

                if not password_filled:
                    raise Exception("无法找到密码输入框")

                time.sleep(0.5)

                # 点击登录按钮
                logger.info("点击登录按钮...")
                submitted = False
                for selector in ['button[type="submit"]', 'button:has-text("Log")', 'button:has-text("Sign")']:
                    try:
                        page.click(selector, timeout=2000)
                        submitted = True
                        logger.success("✓ 已点击登录按钮")
                        break
                    except:
                        continue

                if not submitted:
                    # 尝试按回车
                    try:
                        page.keyboard.press("Enter")
                        submitted = True
                        logger.success("✓ 已按回车键")
                    except:
                        pass

                # 等待登录完成
                logger.info("等待登录完成...")
                for i in range(30):
                    time.sleep(1)
                    if 'main.aspx' in page.url:
                        logger.success("✓ 登录成功！")
                        break

            # 提取 cookies
            logger.info("提取 cookies...")
            cookies = context.cookies()

            req_client_id = None
            org_id = None

            for cookie in cookies:
                if cookie['name'] == 'ReqClientId':
                    req_client_id = cookie['value']
                elif cookie['name'] == 'orgId':
                    org_id = cookie['value']

            if not req_client_id or not org_id:
                raise Exception("无法提取 cookies")

            logger.success(f"✓ Cookies 已提取")
            logger.info(f"  ReqClientId: {req_client_id[:20]}...")
            logger.info(f"  orgId: {org_id[:20]}...")

            return {
                'ReqClientId': req_client_id,
                'orgId': org_id
            }

        finally:
            logger.info("关闭浏览器...")
            browser.close()
            logger.success("✓ 浏览器已关闭")


def query_ad(employee_id: str, domain: str = "macausjm-glp.com"):
    """查询 AD"""
    logger.info(f"查询 AD: EmployeeId={employee_id}")

    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:
        error = result.stderr.strip()
        if "Cannot find" in error:
            raise Exception(f"用户不存在: EmployeeId='{employee_id}'")
        raise Exception(f"AD 查询错误: {error}")

    if not result.stdout.strip():
        raise Exception(f"用户不存在: EmployeeId='{employee_id}'")

    try:
        user_data = json.loads(result.stdout)
    except:
        raise Exception(f"AD 查询失败")

    if not user_data or not isinstance(user_data, dict):
        raise Exception(f"用户不存在: EmployeeId='{employee_id}'")

    display_name = user_data.get('DisplayName')
    if not display_name:
        raise Exception(f"DisplayName 为空")

    logger.success(f"✓ 找到用户: {display_name}")
    return user_data


def main():
    """主函数"""

    # 加载配置
    if not os.path.exists("config.json"):
        print("错误: config.json 不存在")
        print("请运行: python mdp_termination.py --config")
        sys.exit(1)

    with open("config.json", "r", encoding="utf-8") as f:
        config = json.load(f)

    crm_url = config['crm_url']
    username = config['crm_username']
    password_file = config.get('password_file', 'password.enc')

    # 解密密码
    try:
        password = PasswordManager.decrypt_password(password_file)
        logger.success(f"✓ 密码已解密 (长度: {len(password)})")
    except Exception as e:
        logger.error(f"❌ 密码解密失败: {e}")
        sys.exit(1)

    # 获取 employee_id
    if len(sys.argv) > 1:
        employee_id = sys.argv[1]
    else:
        employee_id = "172034"

    logger.info("="*60)
    logger.info(f"  处理用户: {employee_id}")
    logger.info("="*60)
    logger.info(f"CRM URL: {crm_url}")
    logger.info(f"用户名: {username}")
    logger.info("")

    try:
        # 查询 AD
        user_info = query_ad(employee_id)
        display_name = user_info['DisplayName']
        logger.info(f"Display Name: {display_name}")

        # 登录 CRM（这里会打开浏览器！）
        logger.info("")
        logger.info("="*60)
        logger.info("  CRM 登录")
        logger.info("="*60)
        logger.info("")

        cookies = login_to_crm(crm_url, username, password)

        logger.success("✓ 所有步骤完成！")

    except Exception as e:
        logger.error(f"❌ 错误: {e}")
        import traceback
        logger.error(traceback.format_exc())
        sys.exit(1)


if __name__ == "__main__":
    main()
