# -*- coding: utf-8 -*-
"""
Core App Views

This module contains core views for the application.
"""

from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_page
from django.views.decorators.http import require_http_methods
from django.conf import settings
from django.db import connection
from django.core.cache import cache
from django.utils import timezone
from django.template.loader import render_to_string
import logging
import sys
import os
import psutil
import redis
from celery import current_app as celery_app

logger = logging.getLogger(__name__)


@login_required
def dashboard(request):
    """
    Main dashboard view.
    """
    context = {
        'user': request.user,
        'title': 'Dashboard'
    }
    return render(request, 'core/dashboard.html', context)


@require_http_methods(["GET"])
def health_check(request):
    """
    Simple health check endpoint for container monitoring.
    """
    try:
        # Basic database check
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
        
        return JsonResponse({
            'status': 'healthy',
            'timestamp': timezone.now().isoformat()
        })
        
    except Exception as e:
        logger.error(f"Health check failed: {str(e)}")
        return JsonResponse({
            'status': 'unhealthy',
            'error': str(e),
            'timestamp': timezone.now().isoformat()
        }, status=503)


@require_http_methods(["GET"])
def detailed_health_check(request):
    """
    Detailed health check with comprehensive system status.
    """
    health_status = {
        'status': 'healthy',
        'timestamp': timezone.now().isoformat(),
        'checks': {}
    }
    
    overall_healthy = True
    
    # Database check
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
        health_status['checks']['database'] = {
            'status': 'healthy',
            'message': 'Database connection successful'
        }
    except Exception as e:
        health_status['checks']['database'] = {
            'status': 'unhealthy',
            'message': f'Database connection failed: {str(e)}'
        }
        overall_healthy = False
    
    # Cache check
    try:
        cache.set('health_check_detailed', 'ok', 10)
        cache_result = cache.get('health_check_detailed')
        if cache_result == 'ok':
            health_status['checks']['cache'] = {
                'status': 'healthy',
                'message': 'Cache is working'
            }
        else:
            raise Exception('Cache test failed')
    except Exception as e:
        health_status['checks']['cache'] = {
            'status': 'unhealthy',
            'message': f'Cache check failed: {str(e)}'
        }
        overall_healthy = False
    
    # Redis check
    try:
        redis_client = redis.Redis.from_url(settings.CELERY_BROKER_URL)
        redis_client.ping()
        health_status['checks']['redis'] = {
            'status': 'healthy',
            'message': 'Redis connection successful'
        }
    except Exception as e:
        health_status['checks']['redis'] = {
            'status': 'unhealthy',
            'message': f'Redis connection failed: {str(e)}'
        }
        overall_healthy = False
    
    # Celery check
    try:
        inspect = celery_app.control.inspect()
        stats = inspect.stats()
        if stats:
            health_status['checks']['celery'] = {
                'status': 'healthy',
                'message': 'Celery workers are running',
                'workers': len(stats)
            }
        else:
            raise Exception('No Celery workers found')
    except Exception as e:
        health_status['checks']['celery'] = {
            'status': 'unhealthy',
            'message': f'Celery check failed: {str(e)}'
        }
        overall_healthy = False
    
    # System resources check
    try:
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        cpu_percent = psutil.cpu_percent(interval=1)
        
        health_status['checks']['system'] = {
            'status': 'healthy',
            'memory_usage': f'{memory.percent}%',
            'disk_usage': f'{disk.percent}%',
            'cpu_usage': f'{cpu_percent}%'
        }
        
        # Alert if resources are high
        if memory.percent > 90 or disk.percent > 90 or cpu_percent > 90:
            health_status['checks']['system']['status'] = 'warning'
            health_status['checks']['system']['message'] = 'High resource usage detected'
            
    except Exception as e:
        health_status['checks']['system'] = {
            'status': 'unhealthy',
            'message': f'System check failed: {str(e)}'
        }
        overall_healthy = False
    
    if not overall_healthy:
        health_status['status'] = 'unhealthy'
        return JsonResponse(health_status, status=503)
    
    return JsonResponse(health_status)


@cache_page(60 * 5)  # Cache for 5 minutes
def system_status(request):
    """
    System status endpoint with basic metrics.
    """
    try:
        # Check database connection
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
        
        # Check cache
        cache.set('health_check', 'ok', 10)
        cache_status = cache.get('health_check') == 'ok'
        
        status = {
            'status': 'healthy',
            'database': 'connected',
            'cache': 'connected' if cache_status else 'disconnected',
            'timestamp': timezone.now().isoformat(),
            'version': getattr(settings, 'VERSION', '1.0.0'),
            'environment': getattr(settings, 'ENVIRONMENT', 'development')
        }
        
        return JsonResponse(status)
        
    except Exception as e:
        logger.error(f"System status check failed: {str(e)}")
        return JsonResponse({
            'status': 'unhealthy',
            'error': str(e),
            'timestamp': timezone.now().isoformat()
        }, status=500)


@require_http_methods(["GET"])
def ping(request):
    """
    Simple ping endpoint.
    """
    return JsonResponse({
        'message': 'pong',
        'timestamp': timezone.now().isoformat()
    })


@require_http_methods(["GET"])
def version_info(request):
    """
    Application version information.
    """
    return JsonResponse({
        'version': getattr(settings, 'VERSION', '1.0.0'),
        'environment': getattr(settings, 'ENVIRONMENT', 'development'),
        'python_version': sys.version,
        'django_version': getattr(settings, 'DJANGO_VERSION', 'unknown'),
        'build_date': getattr(settings, 'BUILD_DATE', 'unknown')
    })


def api_documentation(request):
    """
    API documentation view.
    """
    context = {
        'title': 'API Documentation',
        'version': getattr(settings, 'VERSION', '1.0.0')
    }
    return render(request, 'core/api_docs.html', context)


def handler404(request, exception=None):
    """
    Custom 404 error handler.
    """
    logger.warning(f"404 error for URL: {request.path}")
    context = {
        'error_code': '404',
        'error_message': 'Page Not Found',
        'error_description': 'The page you are looking for does not exist.',
    }
    return render(request, 'errors/error.html', context, status=404)


def handler500(request):
    """
    Custom 500 error handler.
    """
    logger.error(f"500 error for URL: {request.path}")
    context = {
        'error_code': '500',
        'error_message': 'Internal Server Error',
        'error_description': 'Something went wrong on our end. Please try again later.',
    }
    return render(request, 'errors/error.html', context, status=500)


def handler403(request, exception=None):
    """
    Custom 403 error handler.
    """
    logger.warning(f"403 error for URL: {request.path} by user: {request.user}")
    context = {
        'error_code': '403',
        'error_message': 'Access Forbidden',
        'error_description': 'You do not have permission to access this resource.',
    }
    return render(request, 'errors/error.html', context, status=403)


def handler400(request, exception=None):
    """
    Custom 400 error handler.
    """
    logger.warning(f"400 error for URL: {request.path}")
    context = {
        'error_code': '400',
        'error_message': 'Bad Request',
        'error_description': 'Your request could not be processed.',
    }
    return render(request, 'errors/error.html', context, status=400)