"""
Project scaffolding generator

Generates standard project structure based on infoman/service architecture.
"""

import os
from pathlib import Path
from typing import Optional


class ProjectScaffold:
    """Project structure generator based on infoman/service standard"""

    # 标准项目目录结构（基于 infoman/service）
    STRUCTURE = {
        "core": {
            "__init__.py": '"""\nCore business logic and application lifecycle\n"""\n',
            "auth.py": '"""\nAuthentication and authorization logic\n"""\n\nfrom infoman.service.core.auth import *\n',
            "response.py": '"""\nStandard API response models\n"""\n\nfrom infoman.service.core.response import *\n',
        },
        "routers": {
            "__init__.py": '"""\nAPI routers and endpoints\n"""\n\nfrom fastapi import APIRouter\n\napi_router = APIRouter()\n\n# Register your routers here\n# from .your_router import your_router\n# api_router.include_router(your_router, prefix="/your-prefix", tags=["Your Tag"])\n',
        },
        "models": {
            "__init__.py": '"""\nData models\n"""\n',
            "entity": {
                "__init__.py": '"""\nDatabase entities (ORM models)\n\nExample:\n    from infoman.service.models.base import BaseModel\n    from sqlalchemy import Column, String, Integer\n\n    class User(BaseModel):\n        __tablename__ = "users"\n\n        id = Column(Integer, primary_key=True)\n        name = Column(String(100), nullable=False)\n        email = Column(String(100), unique=True)\n"""\n',
            },
            "dto": {
                "__init__.py": '"""\nData Transfer Objects (API request/response models)\n\nExample:\n    from pydantic import BaseModel, EmailStr\n\n    class UserCreateDTO(BaseModel):\n        name: str\n        email: EmailStr\n\n    class UserResponseDTO(BaseModel):\n        id: int\n        name: str\n        email: str\n"""\n',
            },
            "schemas": {
                "__init__.py": '"""\nPydantic schemas for data validation\n"""\n',
            },
        },
        "repository": {
            "__init__.py": '"""\nData access layer (Repository pattern)\n\nExample:\n    from sqlalchemy.ext.asyncio import AsyncSession\n    from sqlalchemy import select\n    from models.entity import User\n\n    class UserRepository:\n        def __init__(self, session: AsyncSession):\n            self.session = session\n\n        async def get_by_id(self, user_id: int) -> User | None:\n            result = await self.session.execute(\n                select(User).where(User.id == user_id)\n            )\n            return result.scalar_one_or_none()\n"""\n',
        },
        "exception": {
            "__init__.py": '"""\nCustom exceptions\n"""\n\nfrom infoman.service.exception import (\n    BaseAPIException,\n    BadRequestException,\n    UnauthorizedException,\n    ForbiddenException,\n    NotFoundException,\n    InternalServerException,\n)\n\n__all__ = [\n    "BaseAPIException",\n    "BadRequestException",\n    "UnauthorizedException",\n    "ForbiddenException",\n    "NotFoundException",\n    "InternalServerException",\n]\n',
        },
        "middleware": {
            "__init__.py": '"""\nCustom middleware\n"""\n\n# You can import infoman\'s built-in middleware:\n# from infoman.service.middleware import LoggingMiddleware, RequestIDMiddleware\n',
        },
        "utils": {
            "__init__.py": '"""\nUtility functions\n"""\n',
            "cache": {
                "__init__.py": '"""\nCache utilities\n"""\n\nfrom infoman.service.utils.cache import *\n',
            },
            "parse": {
                "__init__.py": '"""\nParsing utilities\n"""\n\nfrom infoman.service.utils.parse import *\n',
            },
        },
        "infrastructure": {
            "__init__.py": '"""\nInfrastructure components (database, cache, mq, etc.)\n"""\n',
            "database": {
                "__init__.py": '"""\nDatabase connection and management\n\nExample:\n    from infoman.service.infrastructure.db_relation import get_db_manager\n\n    db_manager = get_db_manager()\n    await db_manager.init()\n"""\n',
            },
            "cache": {
                "__init__.py": '"""\nCache management\n\nExample:\n    from infoman.service.infrastructure.db_cache import get_cache_manager\n\n    cache_manager = get_cache_manager()\n    await cache_manager.init()\n"""\n',
            },
        },
        "services": {
            "__init__.py": '"""\nBusiness logic services\n\nExample:\n    class UserService:\n        def __init__(self, user_repo: UserRepository):\n            self.user_repo = user_repo\n\n        async def create_user(self, user_data: UserCreateDTO) -> UserResponseDTO:\n            # Business logic here\n            pass\n"""\n',
        },
    }

    def __init__(self, project_name: str, target_dir: Optional[Path] = None):
        """
        初始化项目脚手架

        Args:
            project_name: 项目名称
            target_dir: 目标目录，默认为当前目录下的项目名称目录
        """
        self.project_name = project_name
        self.target_dir = target_dir or Path.cwd() / project_name

    def create_structure(self, structure: dict, parent_path: Path) -> None:
        """
        递归创建目录结构

        Args:
            structure: 目录结构字典
            parent_path: 父目录路径
        """
        for name, content in structure.items():
            current_path = parent_path / name

            if isinstance(content, dict):
                # 创建目录
                current_path.mkdir(parents=True, exist_ok=True)
                # 递归创建子结构
                self.create_structure(content, current_path)
            else:
                # 创建文件
                current_path.parent.mkdir(parents=True, exist_ok=True)
                with open(current_path, "w", encoding="utf-8") as f:
                    f.write(content)

    def create_config_files(self) -> None:
        """创建配置文件"""
        # .env.example
        env_example = """# Application Settings
ENV=dev
APP_NAME={project_name}
APP_HOST=0.0.0.0
APP_PORT=8000
APP_BASE_URI=
LOG_LEVEL=INFO
LOG_FORMAT=json

# Database (optional)
# ORM backend: tortoise or sqlalchemy
# ORM_BACKEND=sqlalchemy

# MySQL
# MYSQL_ENABLED=false
# MYSQL_HOST=localhost
# MYSQL_PORT=3306
# MYSQL_USER=root
# MYSQL_PASSWORD=
# MYSQL_DATABASE={project_name}

# PostgreSQL (optional)
# PGSQL_ENABLED=false
# PGSQL_HOST=localhost
# PGSQL_PORT=5432
# PGSQL_USER=postgres
# PGSQL_PASSWORD=
# PGSQL_DATABASE={project_name}

# Redis (optional)
# REDIS_ENABLED=false
# REDIS_HOST=localhost
# REDIS_PORT=6379
# REDIS_DB=0
# REDIS_PASSWORD=

# Vector Database (optional)
# QDRANT_ENABLED=false
# QDRANT_HOST=localhost
# QDRANT_PORT=6333

# Message Queue (optional)
# NATS_ENABLED=false
# NATS_URL=nats://localhost:4222

# LLM (optional)
# LLM_PROVIDER=openai
# LLM_API_KEY=
# LLM_MODEL=gpt-4
# LLM_BASE_URL=
""".format(project_name=self.project_name)

        (self.target_dir / ".env.example").write_text(env_example, encoding="utf-8")

        # pyproject.toml
        pyproject = """[project]
name = "{project_name}"
version = "0.1.0"
description = "A project built with infomankit"
requires-python = ">=3.11"

dependencies = [
    "infomankit[web]>=0.3.0",
]

[project.optional-dependencies]
# Add database support
database = [
    "infomankit[database-alchemy]",
]

# Add full features
full = [
    "infomankit[full]",
]

dev = [
    "pytest>=8.0.0",
    "pytest-asyncio>=0.23.0",
    "ruff>=0.14.10",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
target-version = "py311"
line-length = 88
select = ["E", "W", "F", "I", "B"]

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
""".format(project_name=self.project_name)

        (self.target_dir / "pyproject.toml").write_text(pyproject, encoding="utf-8")

        # README.md
        readme = """# {project_name}

A project built with [infomankit](https://github.com/infoman-lib/infoman-pykit).

## Setup

1. Install dependencies:
```bash
pip install -e .
```

2. Copy environment file:
```bash
cp .env.example .env
```

3. Edit `.env` with your configuration.

## Development

Run the development server:
```bash
infoman-serve run main:app --reload
```

Visit http://localhost:8000/docs for API documentation.

## Project Structure

This project follows infomankit's standard architecture:

```
{project_name}/
├── core/                # Core business logic and lifecycle
├── routers/             # API endpoints and routing
├── models/              # Data models
│   ├── entity/          # Database ORM models
│   ├── dto/             # API request/response models
│   └── schemas/         # Pydantic validation schemas
├── repository/          # Data access layer
├── services/            # Business logic services
├── exception/           # Custom exceptions
├── middleware/          # Custom middleware
├── infrastructure/      # Database, cache, MQ connections
└── utils/               # Utility functions
```

## API Development

### 1. Define Data Models

Create ORM model in `models/entity/`:
```python
from infoman.service.models.base import BaseModel
from sqlalchemy import Column, String, Integer

class User(BaseModel):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    email = Column(String(100), unique=True)
```

### 2. Create DTOs

Define API models in `models/dto/`:
```python
from pydantic import BaseModel, EmailStr

class UserCreateDTO(BaseModel):
    name: str
    email: EmailStr

class UserResponseDTO(BaseModel):
    id: int
    name: str
    email: str
```

### 3. Implement Repository

Create data access in `repository/`:
```python
class UserRepository:
    async def create(self, user: UserCreateDTO) -> User:
        # Implementation
        pass
```

### 4. Create Service

Implement business logic in `services/`:
```python
class UserService:
    def __init__(self, repo: UserRepository):
        self.repo = repo

    async def register_user(self, data: UserCreateDTO):
        # Business logic
        pass
```

### 5. Add API Endpoint

Create router in `routers/`:
```python
from fastapi import APIRouter

router = APIRouter(prefix="/users", tags=["Users"])

@router.post("/", response_model=UserResponseDTO)
async def create_user(data: UserCreateDTO):
    # Handler logic
    pass
```

Register in `routers/__init__.py`:
```python
from .user_router import router as user_router
api_router.include_router(user_router)
```

## Testing

```bash
pytest
```

## Built with infomankit

This project uses infomankit's features:
- FastAPI application factory
- Async database support (Tortoise ORM / SQLAlchemy)
- Redis caching
- Logging and monitoring
- Exception handling
- Middleware system

For more information, visit: https://github.com/infoman-lib/infoman-pykit
""".format(project_name=self.project_name)

        (self.target_dir / "README.md").write_text(readme, encoding="utf-8")

        # main.py
        main_py = '''"""
{project_name} - Main Application Entry Point

Built with infomankit framework.
"""

from fastapi import FastAPI
from infoman.service.app import create_app
from infoman.logger import get_logger

# Import routers
from routers import api_router

logger = get_logger(__name__)

# Create FastAPI application using infomankit
app = create_app(
    title="{project_name}",
    description="API service built with infomankit",
    version="0.1.0",
)

# Register routers
app.include_router(api_router)


@app.get("/")
async def root():
    """Root endpoint - Health check"""
    return {{
        "status": "ok",
        "service": "{project_name}",
        "version": "0.1.0",
    }}


@app.get("/health")
async def health():
    """Detailed health check"""
    return {{
        "status": "healthy",
        "service": "{project_name}",
        "checks": {{
            "api": "ok",
        }}
    }}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
'''.format(project_name=self.project_name)

        (self.target_dir / "main.py").write_text(main_py, encoding="utf-8")

        # .gitignore
        gitignore = """# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
ENV/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Environment
.env
.env.local
.env.*.local

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~

# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/

# Logs
*.log
logs/

# Database
*.db
*.sqlite
*.sqlite3

# OS
.DS_Store
Thumbs.db
"""

        (self.target_dir / ".gitignore").write_text(gitignore, encoding="utf-8")

    def generate(self) -> None:
        """生成完整的项目结构"""
        if self.target_dir.exists():
            raise FileExistsError(f"Directory '{self.target_dir}' already exists")

        # 创建项目根目录
        self.target_dir.mkdir(parents=True, exist_ok=True)

        # 创建标准目录结构
        self.create_structure(self.STRUCTURE, self.target_dir)

        # 创建配置文件
        self.create_config_files()

        print(f"✓ Project '{self.project_name}' created successfully!")
        print(f"\nProject structure follows infomankit's standard architecture.")
        print(f"\nNext steps:")
        print(f"  cd {self.project_name}")
        print(f"  pip install -e .")
        print(f"  cp .env.example .env")
        print(f"  # Edit .env with your configuration")
        print(f"  infoman-serve run main:app --reload")
        print(f"\nVisit http://localhost:8000/docs for API documentation.")
