import os
import shutil
from jinja2 import Environment, FileSystemLoader
from .config import CurdGenConfig
from .db import TableMetadata
from typing import List

class Generator:
    def __init__(self, config: CurdGenConfig):
        self.config = config
        template_dir = os.path.join(os.path.dirname(__file__), "templates")
        self.env = Environment(loader=FileSystemLoader(template_dir))
        
    def generate(self, tables: List[TableMetadata], overwrite: bool = False):
        output_dir = self.config.gen.output_dir
        base_package = self.config.gen.base_package
        app_dir = os.path.join(output_dir, base_package)
        
        if overwrite and os.path.exists(app_dir):
            # 安全检查：避免删除当前目录或根目录
            abs_app_dir = os.path.abspath(app_dir)
            if abs_app_dir == os.getcwd() or abs_app_dir == os.path.abspath(output_dir):
                print(f"警告: 跳过删除根目录或当前目录: {app_dir}")
            else:
                print(f"正在清理输出目录: {app_dir}")
                shutil.rmtree(app_dir)
            
        # 1. 创建基础目录
        os.makedirs(app_dir, exist_ok=True)
        os.makedirs(os.path.join(app_dir, "shared"), exist_ok=True)
        os.makedirs(os.path.join(app_dir, "domain"), exist_ok=True)
        os.makedirs(os.path.join(app_dir, "features", "database_basics"), exist_ok=True)
        
        # 创建 __init__.py
        self._touch(os.path.join(app_dir, "__init__.py"))
        self._touch(os.path.join(app_dir, "shared", "__init__.py"))
        self._touch(os.path.join(app_dir, "domain", "__init__.py"))
        self._touch(os.path.join(app_dir, "features", "__init__.py"))
        self._touch(os.path.join(app_dir, "features", "database_basics", "__init__.py"))
        
        # 2. 生成 Shared 文件
        self._generate_shared_files()
        
        # 3. 生成每个表的 Domain 和 Features
        for table in tables:
            # Domain model
            self._render_to_file("domain_model.jinja2",
                                os.path.join(app_dir, "domain", f"{table.name}_model.py"),
                                table=table, base_package=base_package, db=self.config.db)
            
            # Features
            feature_dir = os.path.join(app_dir, "features", "database_basics", table.name)
            os.makedirs(feature_dir, exist_ok=True)
            self._touch(os.path.join(feature_dir, "__init__.py"))
            
            # Create, Get List, Get By ID, Update, Delete
            self._render_to_file("feature_create.jinja2",
                                os.path.join(feature_dir, "create.py"),
                                table=table, base_package=base_package)
            self._render_to_file("feature_get_list.jinja2",
                                os.path.join(feature_dir, "get_list.py"),
                                table=table, base_package=base_package)
            self._render_to_file("feature_get_by_id.jinja2",
                                os.path.join(feature_dir, "get_by_id.py"),
                                table=table, base_package=base_package)
            self._render_to_file("feature_update.jinja2",
                                os.path.join(feature_dir, "update.py"),
                                table=table, base_package=base_package)
            self._render_to_file("feature_delete.jinja2",
                                os.path.join(feature_dir, "delete.py"),
                                table=table, base_package=base_package)
            
        # 4. 生成 main.py
        self._render_to_file("app_main.jinja2",
                            os.path.join(app_dir, "main.py"),
                            tables=tables, base_package=base_package)
        
        print(f"代码已成功生成至: {output_dir}")

    def _generate_shared_files(self):
        output_dir = self.config.gen.output_dir
        base_package = self.config.gen.base_package
        app_dir = os.path.join(output_dir, base_package)
        
        os.makedirs(os.path.join(app_dir, "shared"), exist_ok=True)
        self._touch(os.path.join(app_dir, "shared", "__init__.py"))
        
        self._render_to_file("shared_database.jinja2", 
                            os.path.join(app_dir, "shared", "database.py"),
                            base_package=base_package,
                            db=self.config.db)

    def _render_to_file(self, template_name: str, output_path: str, **kwargs):
        template = self.env.get_template(template_name)
        content = template.render(**kwargs)
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(content)

    def _touch(self, path: str):
        with open(path, "a"):
            pass
