# Generates flask application structure

run_sh_contents = """
#!/bin/bash
export FLASK_APP=run.py
export FLASK_ENV=development
flask run
"""

requirements_txt_contents = """
Flask
Flask-SQLAlchemy
Flask-Migrate
Flask-Cors
python-dotenv
"""

env_contents = """
SQLALCHEMY_DATABASE_URI=sqlite:///database/database.db
SQLALCHEMY_TRACK_MODIFICATIONS=False
SECRET_KEY=your_secret_key_here
"""

config_contents = """
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'your_default_secret_key_here'
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI') or 'sqlite:///' + os.path.join(basedir, 'database.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    DEBUG = False
"""

run_py_contents = """
from api import create_app
app = create_app()

if __name__ == '__main__':
    app.run()
"""

extensions_py_contents = """
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_cors import CORS

db = SQLAlchemy()
migrate = Migrate()
cors = CORS()
"""

api_init_py_contents = """
from flask import Flask
from .config.config import Config
from .extensions import db, migrate, cors

# App factory function to create the Flask application
def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    # Initialize extensions
    db.init_app(app)
    migrate.init_app(app, db)
    cors.init_app(app)

    with app.app_context():
        # Import and register blueprints
        from .routes.blueprint_index import blueprint as index_blueprint
        app.register_blueprint(index_blueprint)

        # Import models to ensure they are registered with SQLAlchemy
        from .models.model_users import User

        # Create database tables
        db.create_all()

    return app
"""

auth_py_contents = """
# Authentication logic and decorators can be added here
"""

blueprint_index_contents = """
from flask import Blueprint, jsonify

blueprint_index = Blueprint('blueprint_index', __name__)

@blueprint_index.route('/')
def index():
    return jsonify({"message": "Welcome to the Flask API, prefabbed with scpygen!"})
"""

model_users_contents = """
from api.extensions import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'
"""

config_contents = """
# Configuration settings for the Flask application
import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'your_default_secret_key_here'
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI') or 'sqlite:///database/database.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
"""

util_contents = """
# Utility functions can be added here
"""

tests_init_py_contents = """
# Test suite initialization
"""

gitignore_contents = """
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
debug.log

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
Pipfile.lock

# pytest
.cache

# mypy
.mypy_cache/
.dmypy.json

# Pyre type checker
.pyre/

# dotenv
.env
.env.*

# VS Code
.vscode/

# Mac
.DS_Store

# Windows
Thumbs.db
"""

readme_md_contents = """
# Flask API Skeleton
This is a basic Flask API skeleton generated by scpygen. It includes essential components such as authentication, database models, and configuration settings.
"""


directories = [
    "api",
    "api/auth",
    "api/routes",
    "api/models",
    "api/config",
    "api/database",
    "api/util",
    "tests"
]

files = [
    "run.py", #done
    "run.sh", #done
    "requirements.txt", #done
    "README.md",
    "extensions.py",
    ".env", #done
    "api/__init__.py", #done
    "api/auth/auth.py", #done
    "api/routes/blueprint_index.py", #done
    "api/database/model_users.py", #done
    "api/config/config.py", #done
    "api/util/util.py", #done
    "tests/__init__.py", #done
    ".gitignore" #done
]

def generate(base_path, project_name):
    """
    Generates a Flask project structure with essential files and directories.
    
    :param base_path: The base path where the project will be created.
    :param project_name: The name of the project.
    """
    import os
    
    # Create project directory
    project_path = os.path.join(base_path, project_name)
    os.makedirs(project_path, exist_ok=True)
    
    # Create directories
    for directory in directories:
        os.makedirs(os.path.join(project_path, directory), exist_ok=True)
    
    # Create files with their contents
    file_contents = {
        "run.py": run_py_contents,
        "run.sh": run_sh_contents,
        "requirements.txt": requirements_txt_contents,
        ".env": env_contents,
        "api/__init__.py": api_init_py_contents,
        "api/auth/auth.py": auth_py_contents,
        "api/routes/blueprint_index.py": blueprint_index_contents,
        "api/models/model_users.py": model_users_contents,
        "api/config/config.py": config_contents,
        "api/util/util.py": util_contents,
        "tests/__init__.py": tests_init_py_contents,
        ".gitignore": gitignore_contents,
        "README.md": readme_md_contents,
        "extensions.py": extensions_py_contents
    }
    
    for file_name, content in file_contents.items():
        with open(os.path.join(project_path, file_name), 'w') as f:
            f.write(content)
    
    print(f"Flask project '{project_name}' generated successfully at {project_path}.")