#!/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/'),
    ('app', 'app'),
]

# 需要隐式导入的模块
hidden_imports = [
    'tkinter',
    'tkinter.ttk',
    'tkinter.filedialog',
    'tkinter.messagebox',
    'tkinter.scrolledtext',
    'pandas',
    'numpy',
    'openpyxl',
    'xlrd',
    'xlwt',
    'xlutils',
    'requests',
    'dotenv',
    'tkinterdnd2',
    'configparser',
    'threading',
    'datetime',
    'json',
    're',
    'subprocess',
    'shutil',
    'app.config.settings',
    'app.services.ocr_service',
    'app.services.order_service',
    'app.services.tobacco_service',
    'app.services.processor_service',
    'app.core.utils.dialog_utils',
    'app.core.utils.file_utils',
    'app.core.utils.log_utils',
    'app.core.utils.string_utils',
    'app.core.handlers.column_mapper',
    'app.core.excel.converter',
    'app.core.db.product_db',
    'app.ui.error_utils',
    'app.ui.theme',
    'app.ui.logging_ui',
    'app.ui.ui_widgets',
    'app.ui.user_settings',
    'app.ui.result_previews',
    'app.ui.command_runner',
    'app.ui.file_operations',
    'app.ui.action_handlers',
    'app.ui.barcode_editor',
    'app.ui.config_dialog',
    'app.ui.shortcuts',
    'app.ui.main_window',
    'app.ui.memory_editor',
]

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("创建便携版打包...")
    
    # 创建发布目录
    release_dir = Path('release')
    if release_dir.exists():
        try:
            shutil.rmtree(release_dir)
        except Exception as e:
            print(f"警告: 无法完全清理发布目录 (可能文件被占用): {e}")
            # 如果目录还在，尝试清理能清理的部分
            for item in release_dir.iterdir():
                try:
                    if item.is_dir(): shutil.rmtree(item)
                    else: item.unlink()
                except Exception: pass
    
    release_dir.mkdir(exist_ok=True)
    
    # 复制exe文件
    exe_file = Path('dist/OCR订单处理系统.exe')
    if exe_file.exists():
        shutil.copy2(exe_file, release_dir)
        print(f"已复制: {exe_file} -> {release_dir}")
    
    # 创建必要的目录结构
    dirs_to_create = ['data/input', 'data/output', 'logs', 'templates', 'config']
    for dir_path in dirs_to_create:
        (release_dir / dir_path).mkdir(parents=True, exist_ok=True)
        print(f"已创建目录: {dir_path}")
    
    # 复制配置文件（包含API密钥）
    config_file = Path('config/config.ini')
    if config_file.exists():
        shutil.copy2(config_file, release_dir / 'config')
        print(f"已复制配置文件: {config_file} -> {release_dir / 'config'}")
    else:
        print(f"警告: 配置文件不存在: {config_file}")
    
    # 复制完整的条码映射文件
    barcode_mapping_file = Path('config/barcode_mappings.json')
    if barcode_mapping_file.exists():
        shutil.copy2(barcode_mapping_file, release_dir / 'config')
        print(f"已复制条码映射文件: {barcode_mapping_file} -> {release_dir / 'config'}")
    else:
        print(f"警告: 条码映射文件不存在: {barcode_mapping_file}")
    
    # 复制根目录的config.ini文件
    root_config_file = Path('config.ini')
    if root_config_file.exists():
        shutil.copy2(root_config_file, release_dir)
        print(f"已复制根配置文件: {root_config_file} -> {release_dir}")
    else:
        print(f"警告: 根配置文件不存在: {root_config_file}")
    
    # 复制模板文件
    template_file = Path('templates/银豹-采购单模板.xls')
    if template_file.exists():
        shutil.copy2(template_file, release_dir / 'templates')
        print(f"已复制模板文件: {template_file} -> {release_dir / 'templates'}")
    else:
        print(f"警告: 模板文件不存在: {template_file}")
    item_file = Path('templates/商品资料.xlsx')
    if item_file.exists():
        try:
            (Path('dist') / 'templates').mkdir(exist_ok=True)
            shutil.copy2(item_file, Path('dist') / 'templates')
        except Exception:
            pass
        shutil.copy2(item_file, release_dir / 'templates')
        print(f"已复制商品资料: {item_file} -> {release_dir / 'templates'}")
    else:
        print(f"警告: 商品资料文件不存在: {item_file}")
    
    # 创建README文件
    readme_content = '''
# OCR订单处理系统 - 便携版

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

## 注意事项
- 首次运行时需要配置百度OCR API密钥
- 支持的图片格式：jpg, jpeg, png, bmp
- 单个文件大小不超过4MB

## 目录结构
- OCR订单处理系统.exe - 主程序
- data/input/ - 输入图片目录
- data/output/ - 输出结果目录
- logs/ - 日志目录
'''
    
    with open(release_dir / 'README.txt', 'w', encoding='utf-8') as f:
        f.write(readme_content)
    print("已创建README.txt")
    
    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())