import os

from flask import Flask, jsonify, request, session
from flask_cors import CORS
from flask_swagger_ui import get_swaggerui_blueprint

app = Flask(__name__)

# Enable CORS for all routes
CORS(app)

# Secret key for session encryption
# python -c "import secrets; print(secrets.token_hex(16))"
app.secret_key = os.environ["SECRET_KEY"]

# Swagger UI configuration
SWAGGER_URL = '/swagger'
API_URL = '/swagger.json'  # Custom route for Swagger JSON

# Create Swagger UI blueprint
swagger_ui_blueprint = get_swaggerui_blueprint(
    SWAGGER_URL,
    API_URL,
    config={
        'app_name': "Task Management API"
    }
)

# Register the Swagger UI blueprint
app.register_blueprint(swagger_ui_blueprint, url_prefix=SWAGGER_URL)

# Define the Swagger JSON specification (manually)
swagger_json = {
    "swagger": "2.0",
    "info": {
        "title": "Task Management API",
        "description": "A simple API to manage tasks",
        "version": "1.0"
    },
    "basePath": "/",
    "paths": {
        "/tasks": {
            "get": {
                "summary": "Get all tasks",
                "operationId": "getTasks",
                "responses": {
                    "200": {
                        "description": "A list of tasks",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/Task"
                            }
                        }
                    }
                }
            },
            "post": {
                "summary": "Add a new task",
                "operationId": "addTask",
                "parameters": [
                    {
                        "name": "task",
                        "in": "body",
                        "description": "Task object to add",
                        "required": True,
                        "schema": {
                            "$ref": "#/definitions/Task"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Task created",
                        "schema": {
                            "$ref": "#/definitions/Task"
                        }
                    }
                }
            }
        },
        "/tasks/{task_id}": {
            "get": {
                "summary": "Get a specific task by ID",
                "operationId": "getTask",
                "parameters": [
                    {
                        "name": "task_id",
                        "in": "path",
                        "type": "integer",
                        "required": True
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A specific task",
                        "schema": {
                            "$ref": "#/definitions/Task"
                        }
                    },
                    "404": {
                        "description": "Task not found"
                    }
                }
            },
            "put": {
                "summary": "Update a specific task by ID",
                "operationId": "updateTask",
                "parameters": [
                    {
                        "name": "task_id",
                        "in": "path",
                        "type": "integer",
                        "required": True
                    },
                    {
                        "name": "task",
                        "in": "body",
                        "description": "Task object to update",
                        "required": True,
                        "schema": {
                            "$ref": "#/definitions/Task"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated task",
                        "schema": {
                            "$ref": "#/definitions/Task"
                        }
                    },
                    "404": {
                        "description": "Task not found"
                    }
                }
            },
            "delete": {
                "summary": "Delete a specific task by ID",
                "operationId": "deleteTask",
                "parameters": [
                    {
                        "name": "task_id",
                        "in": "path",
                        "type": "integer",
                        "required": True
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Task deleted"
                    },
                    "404": {
                        "description": "Task not found"
                    }
                }
            }
        }
    },
    "definitions": {
        "Task": {
            "type": "object",
            "properties": {
                "title": {
                    "type": "string",
                    "example": "Task Name"
                },
                "completed": {
                    "type": "boolean",
                    "example": False
                }
            },
            "required": ["title", "completed"] 
        }
    }
}

# Route to serve the Swagger JSON
@app.route('/swagger.json')
def swagger_json_route():
    return jsonify(swagger_json)

# Utility to get the current user's tasks from session
def get_user_tasks():
    if 'tasks' not in session:
        session['tasks'] = []  # Initialize if not present
    return session['tasks']

# Utility to get the current user's next task ID from session
def get_next_task_id():
    tasks = get_user_tasks()
    if tasks:
        return max(task['id'] for task in tasks) + 1
    return 1  # Start with 1 if no tasks exist yet

# Welcome page (index route)
@app.route('/')
def index():
    info = {
        "message": "Welcome to the Task Management API",
        "description": "This API allows you to manage tasks. You can view, add, update, and delete tasks.",
        "available_endpoints": {
            "GET /tasks": "Retrieve a list of all tasks",
            "GET /tasks/<id>": "Retrieve a specific task by ID",
            "POST /tasks": "Add a new task",
            "PUT /tasks/<id>": "Update an existing task",
            "DELETE /tasks/<id>": "Delete a task by ID"
        },
        "contact": "For any questions, contact support@taskapi.com"
    }
    return jsonify(info)

# Route to serve tasks for the current user
@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks = get_user_tasks()
    return jsonify({"tasks": tasks})

@app.route('/tasks', methods=['POST'])
def add_task():
    data = request.get_json()
    tasks = get_user_tasks()
    task_id = get_next_task_id()  # Get the next auto-incrementing ID
    new_task = {
        "id": task_id,
        "title": data['title'],
        "completed": data.get('completed', False),
    }
    tasks.append(new_task)
    session['tasks'] = tasks  # Save the updated tasks in the session
    return jsonify({"task": new_task}), 201

@app.route('/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = next((task for task in get_user_tasks() if task['id'] == task_id), None)
    if task is None:
        return jsonify({"error": "Task not found"}), 404
    return jsonify({"task": task})

@app.route('/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    task = next((task for task in get_user_tasks() if task['id'] == task_id), None)
    if task is None:
        return jsonify({"error": "Task not found"}), 404
    
    data = request.get_json()
    task['title'] = data.get('title', task['title'])
    task['completed'] = data.get('completed', task['completed'])
    
    tasks = get_user_tasks()
    session['tasks'] = tasks  # Save the updated tasks in the session
    
    return jsonify({"task": task})

@app.route('/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    task = next((task for task in get_user_tasks() if task['id'] == task_id), None)
    if task is None:
        return jsonify({"error": "Task not found"}), 404
    
    tasks = get_user_tasks()
    tasks.remove(task)
    session['tasks'] = tasks  # Save the updated tasks in the session
    return jsonify({"message": "Task deleted"}), 200

if __name__ == '__main__':
    app.run(debug=True)
