# Generates a full stack flask application structure

run_py_contents = """
from app import create_app

app = create_app()

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

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

env_contents = """
SQLALCHEMY_DATABASE_URI=sqlite:///app/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'
    db_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'database', 'database.db')
    abs_db_path = os.path.abspath(db_path)
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI') or f"sqlite:///{abs_db_path}"
    SQLALCHEMY_TRACK_MODIFICATIONS = False
"""

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

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

flask_env_contents = """
FLASK_APP=run.py
FLASK_ENV=development
"""

app_init_py_contents = """
from flask import Flask
from .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)
    cors.init_app(app)

    # Register blueprints
    from .routes.main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app
"""

models_init_py_contents = """
from .user import User
"""

models_user_py_contents = """
from ..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)
    password = db.Column(db.String(200), nullable=False)

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

app_routes_init_py_contents = """
from .main import main as main_blueprint
"""

app_routes_main_py_contents = """
from flask import Blueprint, render_template

main = Blueprint('main', __name__)

@main.route('/')
def index():
    return render_template('index.html')
"""

readme_md_contents = """
# Flask Application Skeleton
This is a basic Flask application skeleton generated by scpygen.
"""

app_views_init_py_contents = """
# This file can be used to initialize view-related logic or imports
"""

templates_index_html_contents = """
<!DOCTYPE html>
<html>
<head>
    <title>SCPYGEN - Flask App</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>Welcome to the Flask Application Skeleton!</h1>
    <div class="subtext"><p>This application was generated using scpygen.</p></div>
    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>
"""

app_static_css_style_css_contents = """
body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    margin: 0;
    padding: 0;
}

h1 {
    text-align: center;
    color: #333;
}

.subtext {
    text-align: center;
    margin-top: 20px;
}
"""

app_static_js_script_js_contents = """
document.addEventListener('DOMContentLoaded', function() {
    console.log('Flask Application Skeleton is ready!');
});
"""

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
"""

directories = [
    "app",
    "app/database",
    "app/models",
    "app/routes",
    "app/views",
    "app/static",
    "app/static/css",
    "app/static/js",
    "app/static/images",
    "app/static/fonts",
    "app/templates",
    "migrations",
    "tests"
]

files = [
    "run.py", # done
    "requirements.txt", # done
    "README.md",
    ".gitignore",
    ".env", # done
    ".flaskenv", # done
    "app/__init__.py", # done
    "app/extensions.py", # done
    "app/config.py", # done
    "app/models/__init__.py", # done
    "app/models/user.py", # done
    "app/routes/__init__.py", # done
    "app/routes/main.py", # done
    "app/views/__init__.py", # done
    "app/templates/index.html", # done
    "app/static/css/style.css", # done
    "app/static/js/script.js", # 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,
        "requirements.txt": requirements_txt_contents,
        ".env": env_contents,
        ".gitignore": gitignore_contents,
        ".flaskenv": flask_env_contents,
        "README.md": readme_md_contents,
        "app/__init__.py": app_init_py_contents,
        "app/extensions.py": extensions_py_contents,
        "app/config.py": config_contents,
        "app/models/__init__.py": models_init_py_contents,
        "app/models/user.py": models_user_py_contents,
        "app/routes/__init__.py": app_routes_init_py_contents,
        "app/routes/main.py": app_routes_main_py_contents,
        "app/views/__init__.py": app_views_init_py_contents,
        "app/templates/index.html": templates_index_html_contents,
        "app/static/css/style.css": app_static_css_style_css_contents,
        "app/static/js/script.js": app_static_js_script_js_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}.")
    return True