import typer
import yaml as pyyaml
import os
from .config import CurdGenConfig
from .db import inspect_db
from .generator import Generator

app = typer.Typer()

@app.command()
def gen(
    config_path: str = typer.Option("curdezgen.yaml", help="配置文件路径"),
    overwrite: bool = typer.Option(False, "--overwrite", "-f", help="如果输出目录已存在，则覆盖它")
):
    """
    根据配置文件，从数据库结构生成 CRUD 代码。
    """
    if not os.path.exists(config_path):
        typer.echo(f"错误: 找不到配置文件 {config_path}。")
        raise typer.Exit(code=1)
        
    with open(config_path, "r", encoding="utf-8") as f:
        config_data = pyyaml.safe_load(f)
        
    config = CurdGenConfig(**config_data)
    
    typer.echo(f"正在检查数据库: {config.db.connection_url}")
    try:
        tables = inspect_db(config.db)
    except Exception:
        typer.echo("错误: 数据库连接失败，请检查配置。")
        raise typer.Exit(code=1)
    
    typer.echo(f"找到 {len(tables)} 张表。正在生成代码...")
    generator = Generator(config)
    generator.generate(tables, overwrite=overwrite)
    
    typer.echo("生成完成！")

@app.command()
def init(
    config_path: str = typer.Option("curdezgen.yaml", help="配置文件路径"),
    force: bool = typer.Option(False, "--force", "-f", help="强制初始化，即使目录已存在")
):
    """
    根据配置文件初始化项目结构 (创建 app 目录及基础文件)。
    """
    if not os.path.exists(config_path):
        typer.echo(f"错误: 找不到配置文件 {config_path}。请先运行 'curdezgen yaml' 生成配置文件。")
        raise typer.Exit(code=1)
        
    with open(config_path, "r", encoding="utf-8") as f:
        config_data = pyyaml.safe_load(f)
        
    config = CurdGenConfig(**config_data)
    project_name = config.gen.base_package
    base_path = os.path.join(config.gen.output_dir, project_name)

    if os.path.exists(base_path) and not force:
        typer.echo(f"警告: 目录 {project_name} 已存在。使用 -f 参数强制重新初始化基础结构。")
        # 我们不退出，因为用户可能只是想补全缺失的基础文件
    
    typer.echo(f"正在初始化项目结构: {project_name}...")
    
    # 1. 创建基础目录
    dirs = ["shared", "domain", "features"]
    os.makedirs(base_path, exist_ok=True)
    for d in dirs:
        os.makedirs(os.path.join(base_path, d), exist_ok=True)
        # 创建 __init__.py
        with open(os.path.join(base_path, d, "__init__.py"), "w") as f:
            pass
    with open(os.path.join(base_path, "__init__.py"), "w") as f:
        pass

    # 2. 生成基础基础设施文件 (database.py 等)
    generator = Generator(config)
    generator._generate_shared_files()
    
    # 3. 创建基础 main.py
    main_py_path = os.path.join(base_path, "main.py")
    if not os.path.exists(main_py_path) or force:
        with open(main_py_path, "w", encoding="utf-8") as f:
            f.write("from fastapi import FastAPI\n\napp = FastAPI(title='CRUD API')\n\n@app.get('/')\nasync def root():\n    return {'message': 'Welcome to CRUD API'}\n")

    typer.echo(f"项目 {project_name} 基础结构初始化成功。")
    typer.echo(f"下一步: 修改 {config_path} 中的数据库配置，然后运行 'curdezgen gen' 生成接口。")

@app.command()
def yaml(
    output: str = typer.Option("curdezgen.yaml", help="配置文件保存路径"),
    force: bool = typer.Option(False, "--force", "-f", help="如果文件已存在，则强制覆盖")
):
    """
    第一步：生成默认配置文件模板。
    """
    if os.path.exists(output) and not force:
        typer.echo(f"错误: 文件 {output} 已存在。使用 -f 参数进行覆盖。")
        raise typer.Exit(code=1)

    default_config = {
        "db": {
            "type": "postgresql",
            "host": "localhost",
            "port": 5432,
            "user": "postgres",
            "password": "your_password",
            "name": "your_db_name",
            "schema_name": "public",
            "tables": None
        },
        "gen": {
            "output_dir": ".",
            "base_package": "app"
        }
    }

    with open(output, "w", encoding="utf-8") as f:
        pyyaml.dump(default_config, f, default_flow_style=False, sort_keys=False)
    
    typer.echo(f"已生成配置文件模板: {output}")
    typer.echo("下一步: 修改该文件中的数据库连接信息，然后运行 'curdezgen init'。")

if __name__ == "__main__":
    app()
