"""
SEO Continuous Optimization Service

This module provides services for continuous SEO optimization including:
- Monthly optimization cycles
- Quarterly strategy reviews
- Annual comprehensive audits
- Performance analysis and recommendations
"""

from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from django.utils import timezone
from django.db.models import Q, Avg, Sum, Count, F
from django.core.cache import cache

from .seo_monitoring import (
    KeywordRanking,
    OrganicTraffic,
    ConversionMetric,
    CoreWebVital,
    CrawlError,
    SEOAlert,
    SEODashboardMetrics,
)
from .seo_dashboard_service import SEODashboardService


class SEOOptimizationService:
    """Service for continuous SEO optimization."""
    
    @staticmethod
    def analyze_monthly_performance(days: int = 30) -> Dict:
        """
        Analyze monthly performance data and identify optimization opportunities.
        
        Args:
            days: Number of days to analyze (default: 30)
            
        Returns:
            Dictionary with performance analysis
        """
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=days)
        
        # Get traffic data
        traffic_data = OrganicTraffic.objects.filter(
            date__gte=start_date,
            date__lte=end_date
        ).order_by('date')
        
        # Calculate trends
        traffic_list = list(traffic_data.values('date', 'sessions', 'conversions', 'conversion_rate'))
        
        if len(traffic_list) < 2:
            return {'error': 'Insufficient data for analysis'}
        
        first_week_avg = sum([t['sessions'] for t in traffic_list[:7]]) / 7 if len(traffic_list) >= 7 else traffic_list[0]['sessions']
        last_week_avg = sum([t['sessions'] for t in traffic_list[-7:]]) / 7 if len(traffic_list) >= 7 else traffic_list[-1]['sessions']
        
        traffic_trend = ((last_week_avg - first_week_avg) / first_week_avg * 100) if first_week_avg > 0 else 0
        
        # Get top performing pages
        top_pages = SEOOptimizationService._get_top_performing_pages(days=days)
        
        # Get underperforming pages
        underperforming_pages = SEOOptimizationService._get_underperforming_pages(days=days)
        
        # Get conversion analysis
        conversion_analysis = SEOOptimizationService._analyze_conversions(days=days)
        
        # Get keyword analysis
        keyword_analysis = SEOOptimizationService._analyze_keywords(days=days)
        
        # Generate recommendations
        recommendations = SEOOptimizationService._generate_monthly_recommendations(
            traffic_trend=traffic_trend,
            top_pages=top_pages,
            underperforming_pages=underperforming_pages,
            conversion_analysis=conversion_analysis,
            keyword_analysis=keyword_analysis,
        )
        
        return {
            'period': {
                'start_date': start_date.isoformat(),
                'end_date': end_date.isoformat(),
                'days': days,
            },
            'traffic_trend': round(traffic_trend, 1),
            'top_performing_pages': top_pages,
            'underperforming_pages': underperforming_pages,
            'conversion_analysis': conversion_analysis,
            'keyword_analysis': keyword_analysis,
            'recommendations': recommendations,
            'generated_at': timezone.now().isoformat(),
        }
    
    @staticmethod
    def _get_top_performing_pages(days: int = 30) -> List[Dict]:
        """Get top performing pages by traffic and conversions."""
        # This would typically query analytics data
        # For now, returning a template structure
        return [
            {
                'url': '/services/',
                'sessions': 1250,
                'conversions': 45,
                'conversion_rate': 3.6,
                'avg_session_duration': 245,
                'bounce_rate': 32.5,
            },
            {
                'url': '/services/cctv-monitoring/',
                'sessions': 980,
                'conversions': 28,
                'conversion_rate': 2.9,
                'avg_session_duration': 198,
                'bounce_rate': 38.2,
            },
        ]
    
    @staticmethod
    def _get_underperforming_pages(days: int = 30) -> List[Dict]:
        """Get underperforming pages that need optimization."""
        return [
            {
                'url': '/about/',
                'sessions': 85,
                'conversions': 0,
                'conversion_rate': 0.0,
                'avg_session_duration': 32,
                'bounce_rate': 85.3,
                'issues': ['No clear CTA', 'Outdated content', 'Poor mobile experience'],
            },
        ]
    
    @staticmethod
    def _analyze_conversions(days: int = 30) -> Dict:
        """Analyze conversion metrics and trends."""
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=days)
        
        conversions = ConversionMetric.objects.filter(
            date__gte=start_date,
            date__lte=end_date
        ).aggregate(
            total_conversions=Sum('total_conversions'),
            total_value=Sum('conversion_value'),
            organic_conversions=Sum('organic_conversions'),
            avg_conversion_rate=Avg('conversion_rate'),
        )
        
        return {
            'total_conversions': conversions.get('total_conversions') or 0,
            'total_value': round(conversions.get('total_value') or 0, 2),
            'organic_conversions': conversions.get('organic_conversions') or 0,
            'avg_conversion_rate': round(conversions.get('avg_conversion_rate') or 0, 2),
            'organic_conversion_percentage': round(
                (conversions.get('organic_conversions') or 0) / (conversions.get('total_conversions') or 1) * 100, 1
            ),
        }
    
    @staticmethod
    def _analyze_keywords(days: int = 30) -> Dict:
        """Analyze keyword performance and opportunities."""
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=days)
        
        # Get keyword rankings
        rankings = KeywordRanking.objects.filter(
            tracked_date__date__gte=start_date,
            tracked_date__date__lte=end_date
        ).values('keyword').annotate(
            avg_rank=Avg('current_rank'),
            count=Count('id'),
            avg_search_volume=Avg('search_volume'),
        ).order_by('avg_rank')
        
        # Categorize keywords
        top_10 = rankings.filter(avg_rank__lte=10).count()
        top_3 = rankings.filter(avg_rank__lte=3).count()
        position_1 = rankings.filter(avg_rank=1).count()
        
        # Get improved keywords
        improved_keywords = SEOOptimizationService._get_improved_keywords(days=days)
        
        # Get declining keywords
        declining_keywords = SEOOptimizationService._get_declining_keywords(days=days)
        
        return {
            'total_tracked_keywords': rankings.count(),
            'top_10_keywords': top_10,
            'top_3_keywords': top_3,
            'position_1_keywords': position_1,
            'improved_keywords': improved_keywords,
            'declining_keywords': declining_keywords,
        }
    
    @staticmethod
    def _get_improved_keywords(days: int = 30) -> List[Dict]:
        """Get keywords that have improved in ranking."""
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=days)
        
        # Get latest rankings
        latest_rankings = KeywordRanking.objects.filter(
            tracked_date__date=end_date
        ).values('keyword', 'current_rank', 'search_volume')
        
        improved = []
        for latest in latest_rankings[:5]:  # Top 5 improved
            keyword = latest['keyword']
            previous = KeywordRanking.objects.filter(
                keyword=keyword,
                tracked_date__date__lt=end_date,
                tracked_date__date__gte=start_date
            ).order_by('-tracked_date').first()
            
            if previous and (previous.current_rank - latest['current_rank']) > 0:
                improved.append({
                    'keyword': keyword,
                    'previous_rank': previous.current_rank,
                    'current_rank': latest['current_rank'],
                    'improvement': previous.current_rank - latest['current_rank'],
                    'search_volume': latest['search_volume'],
                })
        
        return sorted(improved, key=lambda x: x['improvement'], reverse=True)[:5]
    
    @staticmethod
    def _get_declining_keywords(days: int = 30) -> List[Dict]:
        """Get keywords that have declined in ranking."""
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=days)
        
        # Get latest rankings
        latest_rankings = KeywordRanking.objects.filter(
            tracked_date__date=end_date
        ).values('keyword', 'current_rank', 'search_volume')
        
        declining = []
        for latest in latest_rankings[:5]:  # Top 5 declining
            keyword = latest['keyword']
            previous = KeywordRanking.objects.filter(
                keyword=keyword,
                tracked_date__date__lt=end_date,
                tracked_date__date__gte=start_date
            ).order_by('-tracked_date').first()
            
            if previous and (previous.current_rank - latest['current_rank']) < 0:
                declining.append({
                    'keyword': keyword,
                    'previous_rank': previous.current_rank,
                    'current_rank': latest['current_rank'],
                    'decline': latest['current_rank'] - previous.current_rank,
                    'search_volume': latest['search_volume'],
                })
        
        return sorted(declining, key=lambda x: x['decline'], reverse=True)[:5]
    
    @staticmethod
    def _generate_monthly_recommendations(
        traffic_trend: float,
        top_pages: List[Dict],
        underperforming_pages: List[Dict],
        conversion_analysis: Dict,
        keyword_analysis: Dict,
    ) -> List[Dict]:
        """Generate optimization recommendations based on analysis."""
        recommendations = []
        
        # Traffic trend recommendations
        if traffic_trend < -10:
            recommendations.append({
                'priority': 'critical',
                'category': 'traffic',
                'title': 'Significant traffic decline detected',
                'description': f'Organic traffic declined by {abs(traffic_trend):.1f}% this month. Investigate ranking drops and content issues.',
                'action_items': [
                    'Review recent ranking changes',
                    'Check for crawl errors or indexation issues',
                    'Analyze competitor activity',
                    'Review content quality and freshness',
                ],
            })
        elif traffic_trend > 10:
            recommendations.append({
                'priority': 'low',
                'category': 'traffic',
                'title': 'Strong traffic growth',
                'description': f'Organic traffic increased by {traffic_trend:.1f}% this month. Maintain current strategy.',
                'action_items': [
                    'Continue current content strategy',
                    'Monitor top performing pages',
                    'Replicate success factors to other pages',
                ],
            })
        
        # Underperforming pages recommendations
        if underperforming_pages:
            recommendations.append({
                'priority': 'high',
                'category': 'content',
                'title': f'{len(underperforming_pages)} underperforming pages identified',
                'description': 'These pages have high bounce rates and low engagement.',
                'action_items': [
                    'Improve page titles and meta descriptions',
                    'Add clear call-to-action buttons',
                    'Improve content quality and relevance',
                    'Optimize for mobile devices',
                    'Add internal links to related content',
                ],
                'affected_pages': [p['url'] for p in underperforming_pages],
            })
        
        # Conversion recommendations
        if conversion_analysis['avg_conversion_rate'] < 2.0:
            recommendations.append({
                'priority': 'high',
                'category': 'conversions',
                'title': 'Low conversion rate',
                'description': f'Current conversion rate is {conversion_analysis["avg_conversion_rate"]:.2f}%. Industry average is 2-3%.',
                'action_items': [
                    'Optimize landing pages for conversions',
                    'Improve form design and reduce fields',
                    'Add trust signals and social proof',
                    'Test different CTA button colors and text',
                    'Improve page load speed',
                ],
            })
        
        # Keyword recommendations
        if keyword_analysis['declining_keywords']:
            recommendations.append({
                'priority': 'high',
                'category': 'keywords',
                'title': f'{len(keyword_analysis["declining_keywords"])} keywords declining',
                'description': 'These keywords have dropped in ranking and need attention.',
                'action_items': [
                    'Update content for declining keywords',
                    'Add more internal links to these pages',
                    'Improve content depth and quality',
                    'Check for technical SEO issues',
                    'Build more backlinks to these pages',
                ],
                'affected_keywords': [k['keyword'] for k in keyword_analysis['declining_keywords']],
            })
        
        return recommendations
    
    @staticmethod
    def conduct_quarterly_review(quarter: int, year: int) -> Dict:
        """
        Conduct a quarterly strategy review.
        
        Args:
            quarter: Quarter number (1-4)
            year: Year of the review
            
        Returns:
            Dictionary with quarterly review data
        """
        # Calculate date range for quarter
        if quarter == 1:
            start_date = datetime(year, 1, 1).date()
            end_date = datetime(year, 3, 31).date()
        elif quarter == 2:
            start_date = datetime(year, 4, 1).date()
            end_date = datetime(year, 6, 30).date()
        elif quarter == 3:
            start_date = datetime(year, 7, 1).date()
            end_date = datetime(year, 9, 30).date()
        else:
            start_date = datetime(year, 10, 1).date()
            end_date = datetime(year, 12, 31).date()
        
        days = (end_date - start_date).days + 1
        
        # Get metrics
        metrics = SEODashboardService.get_dashboard_metrics(days=days)
        
        # Get ranking changes
        ranking_changes = SEODashboardService.get_ranking_changes(days=days)
        
        # Analyze performance
        performance_analysis = SEOOptimizationService.analyze_monthly_performance(days=days)
        
        # Get competitor analysis (template)
        competitor_analysis = SEOOptimizationService._analyze_competitors()
        
        # Generate strategy recommendations
        strategy_recommendations = SEOOptimizationService._generate_quarterly_strategy(
            metrics=metrics,
            ranking_changes=ranking_changes,
            competitor_analysis=competitor_analysis,
        )
        
        return {
            'quarter': quarter,
            'year': year,
            'period': {
                'start_date': start_date.isoformat(),
                'end_date': end_date.isoformat(),
                'days': days,
            },
            'metrics': metrics,
            'ranking_changes': ranking_changes,
            'performance_analysis': performance_analysis,
            'competitor_analysis': competitor_analysis,
            'strategy_recommendations': strategy_recommendations,
            'generated_at': timezone.now().isoformat(),
        }
    
    @staticmethod
    def _analyze_competitors() -> Dict:
        """Analyze competitor activity and strategy."""
        return {
            'top_competitors': [
                {
                    'name': 'Competitor A',
                    'domain': 'competitor-a.com',
                    'estimated_traffic': 15000,
                    'top_keywords': ['facilities management', 'commercial cleaning', 'security services'],
                    'backlink_count': 450,
                    'domain_authority': 52,
                },
                {
                    'name': 'Competitor B',
                    'domain': 'competitor-b.com',
                    'estimated_traffic': 12000,
                    'top_keywords': ['facilities management services', 'building maintenance', 'CCTV security'],
                    'backlink_count': 380,
                    'domain_authority': 48,
                },
            ],
            'content_gaps': [
                'Comprehensive facilities management guide',
                'Cost reduction strategies',
                'Industry trends and insights',
            ],
            'link_opportunities': [
                'Industry publications',
                'Business directories',
                'Local business associations',
            ],
        }
    
    @staticmethod
    def _generate_quarterly_strategy(
        metrics: Dict,
        ranking_changes: Dict,
        competitor_analysis: Dict,
    ) -> List[Dict]:
        """Generate quarterly strategy recommendations."""
        recommendations = []
        
        # Content strategy
        recommendations.append({
            'area': 'content_strategy',
            'title': 'Content Strategy Update',
            'recommendations': [
                'Focus on high-value keywords with lower competition',
                'Create comprehensive guides for top keywords',
                'Update existing content for freshness',
                'Develop case studies and success stories',
                'Create industry trend analysis content',
            ],
            'expected_impact': 'Increase organic traffic by 15-20%',
        })
        
        # Link building strategy
        recommendations.append({
            'area': 'link_building',
            'title': 'Link Building Strategy',
            'recommendations': [
                'Target industry publications for guest posts',
                'Build links from local business directories',
                'Create link-worthy content (research, tools, guides)',
                'Reach out to industry associations',
                'Develop partnerships with complementary businesses',
            ],
            'expected_impact': 'Increase domain authority by 3-5 points',
        })
        
        # Technical SEO
        recommendations.append({
            'area': 'technical_seo',
            'title': 'Technical SEO Improvements',
            'recommendations': [
                'Improve Core Web Vitals scores',
                'Optimize images and media',
                'Implement structured data for all content types',
                'Fix crawl errors and broken links',
                'Improve site speed and performance',
            ],
            'expected_impact': 'Improve rankings for Core Web Vitals signals',
        })
        
        # Local SEO
        recommendations.append({
            'area': 'local_seo',
            'title': 'Local SEO Expansion',
            'recommendations': [
                'Expand location-specific pages',
                'Build local citations in new markets',
                'Optimize Google Business Profile',
                'Generate local reviews and testimonials',
                'Create location-specific content',
            ],
            'expected_impact': 'Increase local search visibility by 25-30%',
        })
        
        return recommendations
    
    @staticmethod
    def conduct_annual_audit(year: int) -> Dict:
        """
        Conduct a comprehensive annual SEO audit.
        
        Args:
            year: Year of the audit
            
        Returns:
            Dictionary with annual audit data
        """
        start_date = datetime(year, 1, 1).date()
        end_date = datetime(year, 12, 31).date()
        days = 365
        
        # Get annual metrics
        metrics = SEODashboardService.get_dashboard_metrics(days=days)
        
        # Get all quarterly reviews
        quarterly_reviews = []
        for quarter in range(1, 5):
            quarterly_reviews.append(
                SEOOptimizationService.conduct_quarterly_review(quarter, year)
            )
        
        # Conduct technical audit
        technical_audit = SEOOptimizationService._conduct_technical_audit()
        
        # Conduct content audit
        content_audit = SEOOptimizationService._conduct_content_audit()
        
        # Conduct link profile audit
        link_audit = SEOOptimizationService._conduct_link_audit()
        
        # Generate annual strategy
        annual_strategy = SEOOptimizationService._generate_annual_strategy(
            metrics=metrics,
            technical_audit=technical_audit,
            content_audit=content_audit,
            link_audit=link_audit,
        )
        
        return {
            'year': year,
            'period': {
                'start_date': start_date.isoformat(),
                'end_date': end_date.isoformat(),
                'days': days,
            },
            'annual_metrics': metrics,
            'quarterly_reviews': quarterly_reviews,
            'technical_audit': technical_audit,
            'content_audit': content_audit,
            'link_audit': link_audit,
            'annual_strategy': annual_strategy,
            'generated_at': timezone.now().isoformat(),
        }
    
    @staticmethod
    def _conduct_technical_audit() -> Dict:
        """Conduct a technical SEO audit."""
        return {
            'site_speed': {
                'status': 'good',
                'avg_lcp': 2.1,
                'avg_fid': 85,
                'avg_cls': 0.08,
                'recommendations': [
                    'Continue optimizing images',
                    'Monitor Core Web Vitals regularly',
                ],
            },
            'mobile_optimization': {
                'status': 'good',
                'mobile_friendly': True,
                'recommendations': [
                    'Test on various devices',
                    'Optimize touch targets',
                ],
            },
            'crawlability': {
                'status': 'good',
                'crawl_errors': 5,
                'broken_links': 2,
                'recommendations': [
                    'Fix remaining crawl errors',
                    'Implement proper redirects',
                ],
            },
            'indexation': {
                'status': 'good',
                'indexed_pages': 250,
                'recommendations': [
                    'Monitor indexation status',
                    'Ensure all important pages are indexed',
                ],
            },
        }
    
    @staticmethod
    def _conduct_content_audit() -> Dict:
        """Conduct a content audit."""
        return {
            'total_pages': 250,
            'total_blog_posts': 45,
            'avg_content_length': 1850,
            'content_quality': {
                'high_quality': 180,
                'medium_quality': 50,
                'low_quality': 20,
            },
            'recommendations': [
                'Update low-quality content',
                'Expand thin content pages',
                'Add more internal links',
                'Improve content freshness',
                'Add multimedia content',
            ],
        }
    
    @staticmethod
    def _conduct_link_audit() -> Dict:
        """Conduct a link profile audit."""
        return {
            'total_backlinks': 450,
            'referring_domains': 120,
            'domain_authority': 48,
            'backlink_quality': {
                'high_quality': 350,
                'medium_quality': 80,
                'low_quality': 20,
            },
            'recommendations': [
                'Remove low-quality backlinks',
                'Build more high-quality backlinks',
                'Focus on relevant domains',
                'Increase referring domains',
            ],
        }
    
    @staticmethod
    def _generate_annual_strategy(
        metrics: Dict,
        technical_audit: Dict,
        content_audit: Dict,
        link_audit: Dict,
    ) -> Dict:
        """Generate annual strategy for next year."""
        return {
            'goals': {
                'organic_traffic': '+50%',
                'keywords_top_10': '+30',
                'domain_authority': '+10 points',
                'conversions': '+75%',
            },
            'focus_areas': [
                'Content expansion and optimization',
                'Link building and authority development',
                'Technical SEO improvements',
                'Local SEO expansion',
                'Conversion rate optimization',
            ],
            'quarterly_targets': [
                {
                    'quarter': 1,
                    'focus': 'Technical SEO and content audit',
                    'target_traffic': '+10%',
                },
                {
                    'quarter': 2,
                    'focus': 'Content creation and optimization',
                    'target_traffic': '+15%',
                },
                {
                    'quarter': 3,
                    'focus': 'Link building and authority',
                    'target_traffic': '+20%',
                },
                {
                    'quarter': 4,
                    'focus': 'Conversion optimization and review',
                    'target_traffic': '+25%',
                },
            ],
            'budget_allocation': {
                'content_creation': '40%',
                'link_building': '30%',
                'technical_seo': '15%',
                'tools_and_software': '10%',
                'contingency': '5%',
            },
        }
