from django.shortcuts import render, redirect
from django.views import View
from django.views.decorators.cache import cache_control
from django.utils.decorators import method_decorator
from usermanagement.models import UserProfile
from codesofy_lib.custom_config import set_user_profile, get_months_dic, get_privilleges, is_authorized, set_menu_items, get_global_master_details, get_local_date
from datetime import date, datetime, timedelta
from django.db.models import Q, F, Count, Sum
from django.db.models.functions import Coalesce
from codesofy_lib.master_details import InvoiceStatus, PaymentMethod, ItemType, PaymentStatus, SRNStatus
from django.db import transaction, IntegrityError
from django.contrib import messages
from django.db.models import DecimalField, ExpressionWrapper, FloatField
from django.db.models.functions import Cast
from django.contrib.admin.views.decorators import staff_member_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.conf import settings
from django.http import HttpResponse
from django.contrib.auth.models import User
import os
import logging
import csv

# ==========================================
# NEW IMPORTS FOR DASHBOARD ANALYTICS
# ==========================================
try:
    from careermanagement.models import Job, JobApplication
except ImportError:
    Job = None
    JobApplication = None

try:
    from blogmanagement.models import BlogPost
except ImportError:
    BlogPost = None

try:
    from projectsmanagement.models import Project
except ImportError:
    Project = None

try:
    from contactmanagement.models import ContactMessage
except ImportError:
    ContactMessage = None

try:
    from employeemanagement.models import Employee
except ImportError:
    Employee = None

# Create your views here.

menu_item = "dashboard"

def set_sub_menu_item(sub_menu_item, context):
    context = set_menu_items(menu_item, sub_menu_item, context)
    return context

def get_local_master_details():
    context = get_global_master_details()
    return context

logger = logging.getLogger(__name__)


@method_decorator(cache_control(no_cache=True, must_revalidate=True, no_store=True), name='dispatch')
class WelcomeView(View):

    user_dashboard = "user_dashboard"
    back_office_dashboard = "back_office_dashboard"
    
    def get(self, request):

        context = get_local_master_details()

        user_profile = set_user_profile(request, context)

        if user_profile is None:
            return redirect('login')

        get_privilleges(user_profile, context)

        # ==============================================
        # FIX: Always show welcome page
        # ==============================================
        return render(request, 'welcome.html', context)


@method_decorator(cache_control(no_cache=True, must_revalidate=True, no_store=True), name='dispatch')
class LogView(View):
    """
    View to display system logs with filtering
    Only accessible to staff/admin users
    """
    
    def get(self, request):
        # Check if user is authenticated
        if not request.user.is_authenticated:
            return redirect('login')
        
        # Check if user has staff/admin permissions
        if not request.user.is_staff:
            messages.error(request, "You don't have permission to view logs.")
            return redirect('welcome')
        
        # Get context with company details
        context = get_local_master_details()
        
        # Set menu items
        context = set_menu_items(menu_item, "system_logs", context)
        
        # Get user profile
        user_profile = set_user_profile(request, context)
        if user_profile is None:
            return redirect('login')
        
        get_privilleges(user_profile, context)
        
        # Get filter parameters
        search_query = request.GET.get('search', '')
        log_level = request.GET.get('log_level', '')
        date_from = request.GET.get('date_from', '')
        date_to = request.GET.get('date_to', '')
        page = request.GET.get('page', 1)
        
        # Path to log file
        log_file_path = os.path.join(settings.BASE_DIR, 'logs', 'user-login-logoff.log')
        
        logs = []
        
        # Check if log file exists
        if os.path.exists(log_file_path):
            try:
                with open(log_file_path, 'r') as file:
                    all_lines = file.readlines()
                    
                    # Parse each line (reverse order - newest first)
                    for line in reversed(all_lines):
                        if line.strip():
                            log_entry = self.parse_log_line(line.strip())
                            if log_entry:
                                logs.append(log_entry)
                    
                    # Apply filters
                    logs = self.apply_filters(logs, search_query, log_level, date_from, date_to)
                    
            except Exception as e:
                logger.error(f"Error reading log file: {str(e)}")
                messages.error(request, f"Error reading log file: {str(e)}")
        else:
            messages.warning(request, "Log file not found. Please login/logout to generate logs.")
        
        # Pagination (20 items per page)
        paginator = Paginator(logs, 20)
        try:
            logs_page = paginator.page(page)
        except PageNotAnInteger:
            logs_page = paginator.page(1)
        except EmptyPage:
            logs_page = paginator.page(paginator.num_pages)
        
        context.update({
            'logs': logs_page,
            'total_logs': len(logs),
            'search_query': search_query,
            'log_level': log_level,
            'date_from': date_from,
            'date_to': date_to,
            'paginator': paginator,
            'menu_item': menu_item,
            'sub_menu_item': 'system_logs',
        })
        
        return render(request, 'logs.html', context)
    
    def parse_log_line(self, line):
        """Parse a log line into structured data"""
        try:
            parts = line.split(' : ')
            if len(parts) >= 5:
                return {
                    'timestamp': parts[0].strip(),
                    'level': parts[1].strip(),
                    'action': parts[2].strip(),
                    'username': parts[3].strip(),
                    'message': parts[4].strip(),
                }
            else:
                return {
                    'timestamp': '',
                    'level': 'INFO',
                    'action': '',
                    'username': 'Unknown',
                    'message': line,
                }
        except Exception:
            return {
                'timestamp': '',
                'level': 'INFO',
                'action': '',
                'username': 'Unknown',
                'message': line,
            }
    
    def apply_filters(self, logs, search_query, log_level, date_from, date_to):
        """Apply filters to log entries"""
        filtered = logs
        
        # Search filter
        if search_query:
            search_query = search_query.lower()
            filtered = [log for log in filtered if 
                       search_query in log.get('username', '').lower() or
                       search_query in log.get('message', '').lower()]
        
        # Log level filter
        if log_level:
            filtered = [log for log in filtered if log.get('level', '').upper() == log_level.upper()]
        
        # Date range filter
        if date_from:
            try:
                date_from_obj = datetime.strptime(date_from, '%Y-%m-%d')
                filtered = [log for log in filtered if log.get('timestamp') and 
                           datetime.strptime(log.get('timestamp').split()[0], '%Y-%m-%d') >= date_from_obj]
            except (ValueError, IndexError):
                pass
        
        if date_to:
            try:
                date_to_obj = datetime.strptime(date_to, '%Y-%m-%d') + timedelta(days=1)
                filtered = [log for log in filtered if log.get('timestamp') and 
                           datetime.strptime(log.get('timestamp').split()[0], '%Y-%m-%d') <= date_to_obj]
            except (ValueError, IndexError):
                pass
        
        return filtered


@method_decorator(cache_control(no_cache=True, must_revalidate=True, no_store=True), name='dispatch')
class ExportLogsView(View):
    """
    Export logs as CSV file
    """
    
    def get(self, request):
        # Check permissions
        if not request.user.is_authenticated:
            return redirect('login')
        
        if not request.user.is_staff:
            messages.error(request, "You don't have permission to export logs.")
            return redirect('welcome')
        
        log_file_path = os.path.join(settings.BASE_DIR, 'logs', 'user-login-logoff.log')
        
        # Create CSV response
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="logs_export.csv"'
        
        writer = csv.writer(response)
        writer.writerow(['Timestamp', 'Level', 'Action', 'Username', 'Message'])
        
        if os.path.exists(log_file_path):
            with open(log_file_path, 'r') as file:
                for line in file:
                    if line.strip():
                        parts = line.strip().split(' : ')
                        if len(parts) >= 5:
                            writer.writerow([parts[0], parts[1], parts[2], parts[3], parts[4]])
                        else:
                            writer.writerow(['', '', '', '', line.strip()])
        
        return response


# ==========================================
# NEW: DASHBOARD ANALYTICS VIEW
# ==========================================

@method_decorator(cache_control(no_cache=True, must_revalidate=True, no_store=True), name='dispatch')
class DashboardAnalyticsView(View):
    """
    Dashboard Analytics view with stats, charts and recent activity
    """
    
    def get(self, request):
        context = get_local_master_details()

        user_profile = set_user_profile(request, context)
        if user_profile is None:
            return redirect('login')

        get_privilleges(user_profile, context)
        context = set_menu_items(menu_item, 'analytics', context)
        context['dt_string'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        context['logged_user_profile'] = user_profile

        # ==========================================
        # STATS CARDS
        # ==========================================
        
        # Total Users
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        new_users_today = User.objects.filter(date_joined__date=date.today()).count()
        
        # Total Jobs
        total_jobs = Job.objects.count() if Job else 0
        published_jobs = Job.objects.filter(status='published').count() if Job else 0
        
        # Total Job Applications
        total_applications = JobApplication.objects.count() if JobApplication else 0
        pending_applications = JobApplication.objects.filter(status='pending').count() if JobApplication else 0
        
        # Total Blog Posts
        total_posts = BlogPost.objects.count() if BlogPost else 0
        published_posts = BlogPost.objects.filter(status='published').count() if BlogPost else 0
        
        # Total Projects
        total_projects = Project.objects.count() if Project else 0
        published_projects = Project.objects.filter(status='published').count() if Project else 0
        
        # Total Contact Messages
        total_messages = ContactMessage.objects.count() if ContactMessage else 0
        unread_messages = ContactMessage.objects.filter(status='unread').count() if ContactMessage else 0
        
        # Total Employees
        total_employees = Employee.objects.count() if Employee else 0
        active_employees = Employee.objects.filter(is_active=True).count() if Employee else 0
        
        context['stats'] = {
            'total_users': total_users,
            'active_users': active_users,
            'new_users_today': new_users_today,
            'total_jobs': total_jobs,
            'published_jobs': published_jobs,
            'total_applications': total_applications,
            'pending_applications': pending_applications,
            'total_posts': total_posts,
            'published_posts': published_posts,
            'total_projects': total_projects,
            'published_projects': published_projects,
            'total_messages': total_messages,
            'unread_messages': unread_messages,
            'total_employees': total_employees,
            'active_employees': active_employees,
        }

        # ==========================================
        # RECENT ACTIVITY
        # ==========================================
        
        # Recent Users (last 5)
        recent_users = User.objects.all().order_by('-date_joined')[:5]
        context['recent_users'] = recent_users
        
        # Recent Job Applications
        if JobApplication:
            recent_applications = JobApplication.objects.all().order_by('-applied_at')[:5]
            context['recent_applications'] = recent_applications
        else:
            context['recent_applications'] = []
        
        # Recent Contact Messages
        if ContactMessage:
            recent_messages = ContactMessage.objects.all().order_by('-created_at')[:5]
            context['recent_messages'] = recent_messages
        else:
            context['recent_messages'] = []
        
        # Recent Blog Posts
        if BlogPost:
            recent_posts = BlogPost.objects.filter(status='published').order_by('-created_at')[:5]
            context['recent_posts'] = recent_posts
        else:
            context['recent_posts'] = []

        return render(request, 'dashboard_analytics.html', context)