#!/usr/bin/env python3
import argparse
import os
import re
from pathlib import Path
import sys
import uvicorn

# --------------------------
# 项目路径配置（根据实际情况修改）
# --------------------------
# 获取脚本所在目录（兼容各种运行方式）
if getattr(sys, 'frozen', False):
    # 如果是打包后的可执行文件
    BASE_DIR = Path(sys.executable).resolve().parent
else:
    # 正常运行的脚本
    BASE_DIR = Path(__file__).resolve().parent

CONTROLLER_DIR = BASE_DIR / "app" / "controllers"
API_DIR = BASE_DIR / "app" / "apis"
REST_DIR = BASE_DIR / "app" / "rests"
MODEL_DIR = BASE_DIR / "app" / "models"

# 确保目录存在
for dir_path in [CONTROLLER_DIR, API_DIR, REST_DIR, MODEL_DIR]:
    dir_path.mkdir(parents=True, exist_ok=True)

# --------------------------
# 模板定义
# --------------------------
CONTROLLER_TEMPLATE = '''from fastapi import Request
from typing import Optional
from LaraFastAPI.Controller import Controller

class {name}Controller(Controller):
    def __init__(self):
        pass

    async def index(self, request: Request):
        """列表页"""
        return self.render("{snake_name}/index.html", {{}})

'''

API_TEMPLATE = '''from fastapi import APIRouter, Request
from typing import Optional


class {name}Api:
    def __init__(self):
        pass

    async def list(self, request: Request):
        """获取列表"""
        return {{
            "code": 200,
            "msg": "success",
            "data": []
        }}

'''

REST_TEMPLATE = '''from fastapi import APIRouter, Request
from typing import Optional
from pydantic import BaseModel
from app.models.{name} import {name}


class {name}Request(BaseModel):
    name: str
    status: int = 1


class {name}Rest:
    def __init__(self):
        pass

    async def index(self, request: Request):
        """列表"""
        return {{
            "code": 200,
            "msg": "success",
            "data": []
        }}

    async def show(self, request: Request, item_id: Optional[int] = None):
        """单条"""
        return {{
            "code": 200,
            "msg": "success",
            "data": {{"id": item_id}}
        }}

    async def store(self, request: Request, data: {name}Request):
        """创建"""
        return {{
            "code": 201,
            "msg": "created",
            "data": data.dict()
        }}

    async def update(self, request: Request, item_id: Optional[int] = None, data: {name}Request = None):
        """更新"""
        return {{
            "code": 200,
            "msg": "updated",
            "data": {{"id": item_id, **data.dict()}}
        }}

    async def destroy(self, request: Request, item_id: Optional[int] = None):
        """删除"""
        return {{
            "code": 204,
            "msg": "deleted",
            "data": {{"id": item_id}}
        }}
'''

MODEL_TEMPLATE = '''from masoniteorm.models import Model

class {name}(Model):
    __table__ = "{snake_name}s"
    __fillable__ = []
'''

# --------------------------
# 工具函数
# --------------------------
def to_snake_case(name: str) -> str:
    """驼峰转下划线"""
    import re
    name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()


def create_file(path: Path, content: str):
    """创建文件"""
    if path.exists():
        print(f"⚠️  文件已存在: {path}")
        overwrite = input("是否覆盖？(y/N): ").strip().lower()
        if overwrite != 'y':
            print("已跳过")
            return
    path.write_text(content, encoding='utf-8')
    print(f"✅ created successfully: {path}")

def add_route_to_routes(file_path: str, import_line: str, route_item: str):
    """
    自动向 routes/web.py 中的 routes 列表添加一条路由记录
    :param file_path: 路由文件路径，例如 "routes/web.py"
    :param import_line: 要插入的导入语句，例如 "from app.controllers.user_controller import user_controller"
    :param route_item: 要插入的路由项，例如 "    ('/users', user_controller()),"
    """
    # 确保文件存在
    if not os.path.exists(file_path):
        os.makedirs("routes", exist_ok=True)
        with open(file_path, "w", encoding="utf-8") as f:
            f.write('routes = [\n]\n')
    
    # 读取文件内容
    with open(file_path, "r", encoding="utf-8") as f:
        content = f.read()

    # ---------------------
    # 1. 自动插入导入语句
    # ---------------------
    if import_line not in content:
        # 找到第一个 import 或上方插入
        import_pattern = r'^(from|import)'
        lines = content.splitlines()
        insert_import_idx = 0
        
        for i, line in enumerate(lines):
            if re.match(import_pattern, line.strip()):
                insert_import_idx = i
                break
        
        lines.insert(insert_import_idx, import_line)
        content = "\n".join(lines)

    # ---------------------
    # 2. 自动插入路由项到 routes 列表
    # ---------------------
    if route_item.strip() not in content:
        # 匹配 routes = [ ... ] 结构
        routes_pattern = r'(routes\s*=\s*\[\s*?)(\n?)'
        replacement = r'\1\n' + route_item + r'\2'
        content = re.sub(routes_pattern, replacement, content, count=1, flags=re.DOTALL)

    # 写入文件
    with open(file_path, "w", encoding="utf-8") as f:
        f.write(content)


def make_controller(name: str):
    """创建普通控制器"""
    snake_name = to_snake_case(name)
    filename = f"{name}Controller.py"
    file_path = CONTROLLER_DIR / filename
    content = CONTROLLER_TEMPLATE.format(name=name, snake_name=snake_name)
    create_file(file_path, content)
    # 注册路由
    import_line = f"from app.controllers.{name}Controller import {name}Controller"
    route_item = f"    ('/{snake_name}s', {name}Controller()),"
    add_route_to_routes(str(BASE_DIR / "routes" / "controller.py"), import_line, route_item)


def make_api(name: str):
    """创建API控制器"""
    snake_name = to_snake_case(name)
    filename = f"{name}Api.py"
    file_path = API_DIR / filename
    content = API_TEMPLATE.format(name=name, snake_name=snake_name)
    create_file(file_path, content)
    # 注册路由
    import_line = f"from app.apis.{name}Api import {name}Api"
    route_item = f"    ('/api/{snake_name}s', {name}Api()),"
    add_route_to_routes(str(BASE_DIR / "routes" / "api.py"), import_line, route_item)


def make_rest(name: str):
    """创建RESTful控制器"""
    snake_name = to_snake_case(name)
    filename = f"{name}Rest.py"
    file_path = REST_DIR / filename
    content = REST_TEMPLATE.format(name=name, snake_name=snake_name)
    create_file(file_path, content)
    # 注册路由
    import_line = f"from app.rests.{name}Rest import {name}Rest"
    route_item = f"    ('/{snake_name}s', {name}Rest()),"
    add_route_to_routes(str(BASE_DIR / "routes" / "rest.py"), import_line, route_item)


def make_model(name: str):
    """创建Model"""
    snake_name = to_snake_case(name)
    filename = f"{name}.py"
    file_path = MODEL_DIR / filename
    content = MODEL_TEMPLATE.format(name=name, snake_name=snake_name)
    create_file(file_path, content)


# --------------------------
# 主入口
# --------------------------
def main():
    parser = argparse.ArgumentParser(description="LaraFast 命令行工具")
    subparsers = parser.add_subparsers(dest="command", help="可用命令")

    # make:controller
    parser_controller = subparsers.add_parser("make:controller", help="create a new controller")
    parser_controller.add_argument("name", help="controller name (e.g. User)")

    # make:api
    parser_api = subparsers.add_parser("make:api", help="create a new API controller")
    parser_api.add_argument("name", help="api name (e.g. User)")

    # make:rest
    parser_rest = subparsers.add_parser("make:rest", help="create a new RESTful controller")
    parser_rest.add_argument("name", help="rest name (e.g. User)")

    # make:model
    parser_model = subparsers.add_parser("make:model", help="create a new model")
    parser_model.add_argument("name", help="model name (e.g. User)")

    # dev
    parser_dev = subparsers.add_parser("dev", help="start development server")

    args = parser.parse_args()

    if args.command == "make:controller":
        make_controller(args.name.title())
    elif args.command == "make:api":
        make_api(args.name.title())
    elif args.command == "make:rest":
        make_rest(args.name.title())
    elif args.command == "make:model":
        make_model(args.name.title())
    elif args.command == "dev":
        uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()