#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
OCR订单处理系统 - EXE打包脚本
============================
自动化打包脚本，包含所有必要的资源文件和配置
"""

import os
import sys
import shutil
import subprocess
from pathlib import Path

def clean_build():
    """清理之前的构建文件"""
    print("清理构建目录...")
    dirs_to_clean = ['build', 'dist', '__pycache__']
    for dir_name in dirs_to_clean:
        if os.path.exists(dir_name):
            shutil.rmtree(dir_name)
            print(f"已删除: {dir_name}")
    
    # 删除spec文件
    spec_files = [f for f in os.listdir('.') if f.endswith('.spec')]
    for spec_file in spec_files:
        os.remove(spec_file)
        print(f"已删除: {spec_file}")

def create_spec_file():
    """创建PyInstaller spec文件"""
    spec_content = '''
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

# 需要包含的数据文件
added_files = [
    ('config.ini', '.'),
    ('config/barcode_mappings.json', 'config/'),
    ('config/config.ini', 'config/'),
    ('templates/银豹-采购单模板.xls', 'templates/'),
]

# 需要隐式导入的模块
hidden_imports = [
        'tkinter',
        'tkinter.ttk',
        'tkinter.filedialog',
        'tkinter.messagebox',
        'tkinter.scrolledtext',
        'pandas',
        'numpy',
        'openpyxl',
        'xlrd',
        'xlwt',
        'xlutils',
        'xlutils.copy',
        'requests',
        'dotenv',
        'tkinterdnd2',
        'configparser',
        'threading',
        'datetime',
        'json',
        're',
        'subprocess',
        'shutil',
        'sqlite3',
        'logging',
        'base64',
        'concurrent.futures',
        'pathlib',
        'typing',
    ]

a = Analysis(
    ['启动器.py'],
    pathex=['.'],
    binaries=[],
    datas=added_files,
    hiddenimports=hidden_imports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='OCR订单处理系统',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
'''
    
    with open('OCR订单处理系统.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)
    print("已创建spec文件: OCR订单处理系统.spec")

def build_exe():
    """构建EXE文件"""
    print("开始构建EXE文件...")
    try:
        # 注入版本信息到根config.ini
        try:
            root_cfg = Path('config.ini')
            from datetime import datetime
            version_str = datetime.now().strftime('%Y.%m.%d.%H%M')
            if root_cfg.exists():
                lines = root_cfg.read_text(encoding='utf-8').splitlines()
                has_app = any(l.strip().lower() == '[app]' for l in lines)
                if not has_app:
                    lines.append('[App]')
                    lines.append(f'version = {version_str}')
                else:
                    # 更新或追加version
                    new_lines = []
                    in_app = False
                    app_written = False
                    for l in lines:
                        if l.strip().lower() == '[app]':
                            in_app = True
                            new_lines.append(l)
                            continue
                        if in_app and l.strip().lower().startswith('version'):
                            new_lines.append(f'version = {version_str}')
                            app_written = True
                            in_app = True
                            continue
                        new_lines.append(l)
                    if not app_written:
                        new_lines.append('version = ' + version_str)
                    lines = new_lines
                root_cfg.write_text('\n'.join(lines), encoding='utf-8')
                print(f"已写入版本号: {version_str}")
        except Exception as e:
            print(f"版本信息注入失败: {e}")
        result = subprocess.run([
            'pyinstaller', 
            'OCR订单处理系统.spec'
        ], check=True, capture_output=True, text=True)
        print("构建成功!")
        print(result.stdout)
        
        # 构建完成后，复制完整的配置文件到dist目录
        dist_dir = Path('dist')
        
        # 复制包含API密钥的配置文件
        config_file = Path('config/config.ini')
        if config_file.exists():
            # 确保config目录存在
            (dist_dir / 'config').mkdir(exist_ok=True)
            shutil.copy2(config_file, dist_dir / 'config')
            print(f"已复制配置文件到dist: {config_file} -> {dist_dir / 'config'}")
        
        # 复制完整的条码映射文件
        barcode_mapping_file = Path('config/barcode_mappings.json')
        if barcode_mapping_file.exists():
            shutil.copy2(barcode_mapping_file, dist_dir / 'config')
            print(f"已复制条码映射文件到dist: {barcode_mapping_file} -> {dist_dir / 'config'}")
        
        # 复制根目录的config.ini文件（覆盖空的配置文件）
        root_config_file = Path('config.ini')
        if root_config_file.exists():
            shutil.copy2(root_config_file, dist_dir)
            print(f"已复制根配置文件到dist: {root_config_file} -> {dist_dir}")
        else:
            print("警告: 根配置文件不存在，将创建缺省版本")
            (dist_dir / 'config.ini').write_text('[App]\nversion = dev\n', encoding='utf-8')
            
    except subprocess.CalledProcessError as e:
        print(f"构建失败: {e}")
        print(f"错误输出: {e.stderr}")
        return False
    return True

def create_portable_package():
    """创建并更新便携版打包，并同步到桌面"""
    print("更新便携版打包...")
    
    # 1. 准备本地 release 目录
    release_dir = Path('release')
    
    # 不再删除整个目录，以保留 data/input 等用户数据
    if not release_dir.exists():
        release_dir.mkdir(parents=True)
        print(f"已创建本地发布目录: {release_dir}")
    else:
        print(f"本地发布目录已存在，将进行增量更新: {release_dir}")
    
    # 2. 更新核心文件到本地 release
    # 复制exe文件
    exe_file = Path('dist/OCR订单处理系统.exe')
    if exe_file.exists():
        shutil.copy2(exe_file, release_dir)
        print(f"已更新 EXE: {exe_file} -> {release_dir}")
    
    # 确保必要的子目录存在
    dirs_to_ensure = ['data/input', 'data/output', 'data/result', 'logs', 'templates', 'config']
    for dir_path in dirs_to_ensure:
        (release_dir / dir_path).mkdir(parents=True, exist_ok=True)
    
    # 复制配置文件
    files_to_copy = [
        (Path('config/config.ini'), release_dir / 'config'),
        (Path('config/barcode_mappings.json'), release_dir / 'config'),
        (Path('config.ini'), release_dir),
        (Path('templates/银豹-采购单模板.xls'), release_dir / 'templates'),
        (Path('templates/商品资料.xlsx'), release_dir / 'templates'),
    ]
    
    for src, dst_dir in files_to_copy:
        if src.exists():
            dst_dir.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dst_dir)
            print(f"已更新文件: {src} -> {dst_dir}")
        else:
            print(f"警告: 源文件不存在，跳过更新: {src}")

    # 3. 创建/更新 README
    readme_content = '''
# OCR订单处理系统 - 便携版

## 使用说明
1. 双击 "OCR订单处理系统.exe" 启动程序
2. 将需要处理的图片文件放入 data/input 目录
3. 处理结果将保存在 data/result 目录 (采购单 Excel)
4. 中间过程文件在 data/output 目录
5. 日志文件保存在 logs 目录

## 注意事项
- 支持的图片格式：jpg, jpeg, png, bmp
- 单个文件大小建议不超过 4MB

## 目录结构
- OCR订单处理系统.exe - 主程序
- data/input/ - 输入图片目录
- data/result/ - 最终采购单目录
- logs/ - 日志目录
'''
    with open(release_dir / 'README.txt', 'w', encoding='utf-8') as f:
        f.write(readme_content)

    # 4. 同步到桌面
    try:
        # 用户指定的特殊桌面路径
        desktop_path = Path(r"F:\Administrator\桌面")
        if not desktop_path.exists():
            # 兜底：如果 F 盘路径不存在，尝试系统默认路径
            desktop_path = Path(os.path.join(os.path.expanduser("~"), "Desktop"))
            
        desktop_release = desktop_path / "OCR系统_Release"
        
        print(f"正在同步到桌面: {desktop_release}")
        
        # 使用自定义的同步逻辑，避免删除目标目录中的其他文件
        def sync_dir(src_root, dst_root):
            if not dst_root.exists():
                dst_root.mkdir(parents=True)
            
            for item in src_root.iterdir():
                dst_item = dst_root / item.name
                if item.is_dir():
                    sync_dir(item, dst_item)
                else:
                    # 如果是文件，直接覆盖更新
                    shutil.copy2(item, dst_item)
        
        sync_dir(release_dir, desktop_release)
        print(f"同步成功！桌面位置: {desktop_release.absolute()}")
        
    except Exception as e:
        print(f"同步到桌面失败: {e}")
    
    print(f"本地便携版更新完成，位置: {release_dir.absolute()}")

def main():
    """主函数"""
    print("=" * 50)
    print("OCR订单处理系统 - EXE打包工具")
    print("=" * 50)
    
    # 检查是否安装了PyInstaller
    try:
        subprocess.run(['pyinstaller', '--version'], check=True, capture_output=True)
    except (subprocess.CalledProcessError, FileNotFoundError):
        print("错误: 未安装PyInstaller")
        print("请运行: pip install pyinstaller")
        return 1
    
    # 清理构建目录
    clean_build()
    
    # 创建spec文件
    create_spec_file()
    
    # 构建EXE
    if not build_exe():
        return 1
    
    # 创建便携版打包
    create_portable_package()
    
    print("\n" + "=" * 50)
    print("打包完成!")
    print("EXE文件位置: dist/OCR订单处理系统.exe")
    print("便携版位置: release/")
    print("=" * 50)
    
    return 0

if __name__ == '__main__':
    sys.exit(main())