# -*- coding: utf-8 -*-
"""
Generate Analytics Reports Management Command
==========================================

Django management command for generating comprehensive analytics reports.
Creates various types of reports including performance summaries, trend analysis,
comparative reports, and custom analytics dashboards.

Command Features:
- Multiple report types and formats
- Automated report generation
- Scheduled report delivery
- Custom report templates
- Data visualization support
- Export to multiple formats
- Email delivery integration
- Report caching and optimization
- Historical data analysis
- Real-time data integration

Report Types:
1. Performance Reports:
   - Campaign performance summaries
   - Channel effectiveness analysis
   - Advertiser ROI reports
   - Revenue and impression metrics

2. Trend Analysis Reports:
   - Time-series analysis
   - Seasonal trend identification
   - Growth rate calculations
   - Forecasting reports

3. Comparative Reports:
   - Period-over-period comparisons
   - Provider performance comparisons
   - Campaign effectiveness comparisons
   - Benchmark analysis

4. Custom Reports:
   - Ad-hoc analysis reports
   - Executive summaries
   - Technical performance reports
   - Compliance and audit reports

Supported Formats:
- PDF reports with charts and graphs
- Excel spreadsheets with data tables
- CSV files for data export
- JSON for API integration
- HTML for web display
- PowerPoint presentations

Delivery Options:
- Email delivery to stakeholders
- FTP/SFTP upload to external systems
- Cloud storage integration
- API endpoint publishing
- Dashboard integration
- Automated scheduling

Usage Examples:
# Generate daily performance report
python manage.py generate_analytics_reports --type=performance --period=daily

# Generate weekly trend analysis
python manage.py generate_analytics_reports --type=trends --period=weekly --format=pdf

# Generate custom report for specific date range
python manage.py generate_analytics_reports --type=custom --start-date=2024-01-01 --end-date=2024-01-31

# Generate and email executive summary
python manage.py generate_analytics_reports --type=executive --email --recipients=exec@company.com

# Generate all reports for previous month
python manage.py generate_analytics_reports --all --period=monthly --month=2024-01

Author: Adtlas Development Team
Version: 1.0.0
Last Updated: 2024
"""

import logging
import os
import tempfile
from datetime import datetime, timedelta, date
from typing import Dict, List, Any, Optional, Tuple
from pathlib import Path
from dataclasses import dataclass
from enum import Enum

from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q, Count, Sum, Avg, F, Case, When
from django.utils import timezone
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from django.core.files.storage import default_storage

from apps.analytics.models import (
    SfrAnalytics, BouyguesAnalytics, Impression, VastResponse,
    PerformanceMetric, AnalyticsReport
)
from apps.campaigns.models import Campaign
from apps.channels.models import Channel
from apps.advertisers.models import Brand
from apps.analytics.constants import (
    REPORT_TYPES, REPORT_STATUS, EXPORT_FORMATS,
    CACHE_KEYS, CACHE_TIMEOUTS
)
from apps.analytics.exceptions import (
    ReportGenerationException, ExportFailedException
)
from apps.analytics.utils import (
    calculate_performance_metrics, generate_trend_analysis,
    create_data_visualization, send_notification
)

# Configure logging
logger = logging.getLogger(__name__)


class ReportType(Enum):
    """
    Enumeration of available report types.
    """
    PERFORMANCE = 'performance'
    TRENDS = 'trends'
    COMPARATIVE = 'comparative'
    EXECUTIVE = 'executive'
    TECHNICAL = 'technical'
    COMPLIANCE = 'compliance'
    CUSTOM = 'custom'
    ALL = 'all'


class ReportPeriod(Enum):
    """
    Enumeration of report periods.
    """
    DAILY = 'daily'
    WEEKLY = 'weekly'
    MONTHLY = 'monthly'
    QUARTERLY = 'quarterly'
    YEARLY = 'yearly'
    CUSTOM = 'custom'


class ExportFormat(Enum):
    """
    Enumeration of export formats.
    """
    PDF = 'pdf'
    EXCEL = 'excel'
    CSV = 'csv'
    JSON = 'json'
    HTML = 'html'
    POWERPOINT = 'powerpoint'


@dataclass
class ReportConfig:
    """
    Configuration for report generation.
    """
    report_type: ReportType
    period: ReportPeriod
    start_date: date
    end_date: date
    format: ExportFormat
    template: Optional[str] = None
    filters: Dict[str, Any] = None
    recipients: List[str] = None
    include_charts: bool = True
    include_raw_data: bool = False
    compress_output: bool = False
    
    def __post_init__(self):
        if self.filters is None:
            self.filters = {}
        if self.recipients is None:
            self.recipients = []


@dataclass
class ReportMetadata:
    """
    Metadata for generated reports.
    """
    report_id: str
    title: str
    description: str
    generated_at: datetime
    file_path: str
    file_size: int
    record_count: int
    generation_time: float
    config: ReportConfig


class Command(BaseCommand):
    """
    Management command for generating analytics reports.
    
    Generates comprehensive analytics reports in various formats
    and delivers them through multiple channels.
    """
    
    help = 'Generate comprehensive analytics reports'
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.generated_reports = []
        self.temp_dir = None
        self.verbose = False
    
    def add_arguments(self, parser):
        """
        Add command line arguments.
        
        Args:
            parser: Argument parser instance
        """
        # Report type arguments
        parser.add_argument(
            '--type',
            choices=[t.value for t in ReportType],
            default='performance',
            help='Type of report to generate'
        )
        
        parser.add_argument(
            '--all',
            action='store_true',
            help='Generate all available report types'
        )
        
        # Period arguments
        parser.add_argument(
            '--period',
            choices=[p.value for p in ReportPeriod],
            default='daily',
            help='Report period'
        )
        
        parser.add_argument(
            '--start-date',
            type=str,
            help='Start date for custom period (YYYY-MM-DD)'
        )
        
        parser.add_argument(
            '--end-date',
            type=str,
            help='End date for custom period (YYYY-MM-DD)'
        )
        
        parser.add_argument(
            '--month',
            type=str,
            help='Month for monthly reports (YYYY-MM)'
        )
        
        # Format arguments
        parser.add_argument(
            '--format',
            choices=[f.value for f in ExportFormat],
            default='pdf',
            help='Export format'
        )
        
        parser.add_argument(
            '--template',
            type=str,
            help='Custom report template name'
        )
        
        # Filter arguments
        parser.add_argument(
            '--campaign',
            type=str,
            help='Filter by campaign ID or name'
        )
        
        parser.add_argument(
            '--channel',
            type=str,
            help='Filter by channel ID or name'
        )
        
        parser.add_argument(
            '--advertiser',
            type=str,
            help='Filter by advertiser ID or name'
        )
        
        parser.add_argument(
            '--provider',
            choices=['sfr', 'bouygues', 'all'],
            default='all',
            help='Filter by analytics provider'
        )
        
        # Output arguments
        parser.add_argument(
            '--output-dir',
            type=str,
            help='Output directory for generated reports'
        )
        
        parser.add_argument(
            '--filename',
            type=str,
            help='Custom filename for the report'
        )
        
        # Delivery arguments
        parser.add_argument(
            '--email',
            action='store_true',
            help='Email the report to recipients'
        )
        
        parser.add_argument(
            '--recipients',
            type=str,
            nargs='+',
            help='Email recipients'
        )
        
        # Content arguments
        parser.add_argument(
            '--include-charts',
            action='store_true',
            default=True,
            help='Include charts and visualizations'
        )
        
        parser.add_argument(
            '--include-raw-data',
            action='store_true',
            help='Include raw data tables'
        )
        
        parser.add_argument(
            '--compress',
            action='store_true',
            help='Compress output files'
        )
        
        # Control arguments
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Generate report metadata without creating files'
        )
        
        parser.add_argument(
            '--force',
            action='store_true',
            help='Overwrite existing reports'
        )
    
    def handle(self, *args, **options):
        """
        Main command handler.
        
        Args:
            *args: Positional arguments
            **options: Command options
        """
        try:
            # Initialize command
            self._initialize_command(options)
            
            # Validate arguments
            self._validate_arguments(options)
            
            # Create report configurations
            report_configs = self._create_report_configs(options)
            
            # Generate reports
            for config in report_configs:
                self._generate_report(config, options)
            
            # Send notifications
            self._send_notifications(options)
            
            # Display summary
            self._display_summary()
            
        except Exception as e:
            self._handle_command_error(e)
            raise CommandError(f"Report generation failed: {e}")
        
        finally:
            # Cleanup temporary files
            self._cleanup_temp_files()
    
    def _initialize_command(self, options: Dict[str, Any]) -> None:
        """
        Initialize command with options.
        
        Args:
            options: Command options dictionary
        """
        self.verbose = options.get('verbosity', 1) > 1
        self.generated_reports = []
        
        # Create temporary directory
        self.temp_dir = tempfile.mkdtemp(prefix='analytics_reports_')
        
        # Configure logging level
        if self.verbose:
            logging.getLogger('apps.analytics').setLevel(logging.DEBUG)
        
        self.stdout.write(
            self.style.SUCCESS(
                f"Analytics report generation command initialized"
            )
        )
        
        if options.get('dry_run', False):
            self.stdout.write(
                self.style.WARNING("DRY RUN MODE: No files will be created")
            )
    
    def _validate_arguments(self, options: Dict[str, Any]) -> None:
        """
        Validate command arguments.
        
        Args:
            options: Command options dictionary
            
        Raises:
            CommandError: If arguments are invalid
        """
        # Validate date arguments
        if options.get('period') == 'custom':
            if not (options.get('start_date') and options.get('end_date')):
                raise CommandError(
                    "Custom period requires both --start-date and --end-date"
                )
        
        # Validate email arguments
        if options.get('email') and not options.get('recipients'):
            raise CommandError(
                "Email delivery requires --recipients"
            )
        
        # Validate output directory
        output_dir = options.get('output_dir')
        if output_dir and not os.path.exists(output_dir):
            try:
                os.makedirs(output_dir, exist_ok=True)
            except OSError as e:
                raise CommandError(f"Cannot create output directory: {e}")
    
    def _create_report_configs(self, options: Dict[str, Any]) -> List[ReportConfig]:
        """
        Create report configurations based on options.
        
        Args:
            options: Command options dictionary
            
        Returns:
            List of report configurations
        """
        configs = []
        
        # Determine report types
        if options.get('all'):
            report_types = [t for t in ReportType if t != ReportType.ALL]
        else:
            report_types = [ReportType(options.get('type', 'performance'))]
        
        # Determine date range
        start_date, end_date = self._get_date_range(options)
        
        # Create filters
        filters = self._create_filters(options)
        
        # Create configuration for each report type
        for report_type in report_types:
            config = ReportConfig(
                report_type=report_type,
                period=ReportPeriod(options.get('period', 'daily')),
                start_date=start_date,
                end_date=end_date,
                format=ExportFormat(options.get('format', 'pdf')),
                template=options.get('template'),
                filters=filters,
                recipients=options.get('recipients', []),
                include_charts=options.get('include_charts', True),
                include_raw_data=options.get('include_raw_data', False),
                compress_output=options.get('compress', False)
            )
            configs.append(config)
        
        return configs
    
    def _get_date_range(self, options: Dict[str, Any]) -> Tuple[date, date]:
        """
        Determine date range for reports.
        
        Args:
            options: Command options dictionary
            
        Returns:
            Tuple of (start_date, end_date)
        """
        period = options.get('period', 'daily')
        
        if period == 'custom':
            try:
                start_date = datetime.strptime(options['start_date'], '%Y-%m-%d').date()
                end_date = datetime.strptime(options['end_date'], '%Y-%m-%d').date()
            except ValueError:
                raise CommandError("Invalid date format. Use YYYY-MM-DD")
            
        elif period == 'daily':
            # Previous day
            target_date = timezone.now().date() - timedelta(days=1)
            start_date = end_date = target_date
            
        elif period == 'weekly':
            # Previous week (Monday to Sunday)
            today = timezone.now().date()
            days_since_monday = today.weekday()
            start_date = today - timedelta(days=days_since_monday + 7)
            end_date = start_date + timedelta(days=6)
            
        elif period == 'monthly':
            if options.get('month'):
                try:
                    year, month = map(int, options['month'].split('-'))
                    start_date = date(year, month, 1)
                    if month == 12:
                        end_date = date(year + 1, 1, 1) - timedelta(days=1)
                    else:
                        end_date = date(year, month + 1, 1) - timedelta(days=1)
                except ValueError:
                    raise CommandError("Invalid month format. Use YYYY-MM")
            else:
                # Previous month
                today = timezone.now().date()
                first_day_this_month = today.replace(day=1)
                end_date = first_day_this_month - timedelta(days=1)
                start_date = end_date.replace(day=1)
                
        elif period == 'quarterly':
            # Previous quarter
            today = timezone.now().date()
            quarter = (today.month - 1) // 3
            if quarter == 0:
                # Previous year Q4
                start_date = date(today.year - 1, 10, 1)
                end_date = date(today.year - 1, 12, 31)
            else:
                start_month = (quarter - 1) * 3 + 1
                end_month = start_month + 2
                start_date = date(today.year, start_month, 1)
                end_date = date(today.year, end_month + 1, 1) - timedelta(days=1)
                
        elif period == 'yearly':
            # Previous year
            year = timezone.now().year - 1
            start_date = date(year, 1, 1)
            end_date = date(year, 12, 31)
            
        else:
            raise CommandError(f"Invalid period: {period}")
        
        return start_date, end_date
    
    def _create_filters(self, options: Dict[str, Any]) -> Dict[str, Any]:
        """
        Create filters based on options.
        
        Args:
            options: Command options dictionary
            
        Returns:
            Dictionary of filters
        """
        filters = {}
        
        # Campaign filter
        if options.get('campaign'):
            filters['campaign'] = options['campaign']
        
        # Channel filter
        if options.get('channel'):
            filters['channel'] = options['channel']
        
        # Advertiser filter
        if options.get('advertiser'):
            filters['advertiser'] = options['advertiser']
        
        # Provider filter
        if options.get('provider', 'all') != 'all':
            filters['provider'] = options['provider']
        
        return filters
    
    def _generate_report(self, config: ReportConfig, options: Dict[str, Any]) -> None:
        """
        Generate a single report.
        
        Args:
            config: Report configuration
            options: Command options
        """
        start_time = timezone.now()
        
        try:
            self.stdout.write(
                f"Generating {config.report_type.value} report "
                f"({config.start_date} to {config.end_date})..."
            )
            
            # Generate report data
            report_data = self._generate_report_data(config)
            
            # Create report file
            if not options.get('dry_run', False):
                report_file = self._create_report_file(config, report_data, options)
                
                # Create metadata
                metadata = self._create_report_metadata(
                    config, report_file, report_data, start_time
                )
                
                self.generated_reports.append(metadata)
                
                # Email report if requested
                if options.get('email'):
                    self._email_report(metadata, config)
                
                self.stdout.write(
                    self.style.SUCCESS(
                        f"Generated {config.report_type.value} report: {report_file}"
                    )
                )
            else:
                # Dry run - just show what would be generated
                self.stdout.write(
                    f"Would generate {config.report_type.value} report "
                    f"with {len(report_data)} records"
                )
                
        except Exception as e:
            error_msg = f"Failed to generate {config.report_type.value} report: {e}"
            logger.error(error_msg, exc_info=True)
            self.stdout.write(self.style.ERROR(error_msg))
            
            if not options.get('force', False):
                raise
    
    def _generate_report_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate data for the report.
        
        Args:
            config: Report configuration
            
        Returns:
            Dictionary containing report data
        """
        if config.report_type == ReportType.PERFORMANCE:
            return self._generate_performance_data(config)
        elif config.report_type == ReportType.TRENDS:
            return self._generate_trends_data(config)
        elif config.report_type == ReportType.COMPARATIVE:
            return self._generate_comparative_data(config)
        elif config.report_type == ReportType.EXECUTIVE:
            return self._generate_executive_data(config)
        elif config.report_type == ReportType.TECHNICAL:
            return self._generate_technical_data(config)
        elif config.report_type == ReportType.COMPLIANCE:
            return self._generate_compliance_data(config)
        elif config.report_type == ReportType.CUSTOM:
            return self._generate_custom_data(config)
        else:
            raise ReportGenerationException(f"Unknown report type: {config.report_type}")
    
    def _generate_performance_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate performance report data.
        
        Args:
            config: Report configuration
            
        Returns:
            Performance data dictionary
        """
        # Get base queryset
        sfr_qs = SfrAnalytics.objects.filter(
            created_at__date__range=[config.start_date, config.end_date]
        )
        bouygues_qs = BouyguesAnalytics.objects.filter(
            created_at__date__range=[config.start_date, config.end_date]
        )
        
        # Apply filters
        sfr_qs, bouygues_qs = self._apply_filters(sfr_qs, bouygues_qs, config.filters)
        
        # Calculate metrics
        performance_data = {
            'summary': {
                'total_impressions': sfr_qs.count() + bouygues_qs.count(),
                'sfr_impressions': sfr_qs.count(),
                'bouygues_impressions': bouygues_qs.count(),
                'date_range': {
                    'start': config.start_date.isoformat(),
                    'end': config.end_date.isoformat()
                }
            },
            'daily_breakdown': self._get_daily_breakdown(sfr_qs, bouygues_qs, config),
            'campaign_performance': self._get_campaign_performance(config),
            'channel_performance': self._get_channel_performance(config),
            'provider_comparison': self._get_provider_comparison(sfr_qs, bouygues_qs)
        }
        
        return performance_data
    
    def _generate_trends_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate trends analysis data.
        
        Args:
            config: Report configuration
            
        Returns:
            Trends data dictionary
        """
        # Placeholder for trends analysis
        return {
            'trend_analysis': 'Trends data would be generated here',
            'forecasts': 'Forecast data would be included',
            'seasonal_patterns': 'Seasonal analysis would be provided'
        }
    
    def _generate_comparative_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate comparative analysis data.
        
        Args:
            config: Report configuration
            
        Returns:
            Comparative data dictionary
        """
        # Placeholder for comparative analysis
        return {
            'period_comparison': 'Period-over-period comparison data',
            'provider_comparison': 'Provider performance comparison',
            'benchmark_analysis': 'Benchmark comparison data'
        }
    
    def _generate_executive_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate executive summary data.
        
        Args:
            config: Report configuration
            
        Returns:
            Executive summary data dictionary
        """
        # Placeholder for executive summary
        return {
            'key_metrics': 'High-level KPIs and metrics',
            'insights': 'Key insights and recommendations',
            'action_items': 'Recommended actions'
        }
    
    def _generate_technical_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate technical performance data.
        
        Args:
            config: Report configuration
            
        Returns:
            Technical data dictionary
        """
        # Placeholder for technical analysis
        return {
            'system_performance': 'System performance metrics',
            'error_analysis': 'Error rates and analysis',
            'optimization_recommendations': 'Technical optimization suggestions'
        }
    
    def _generate_compliance_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate compliance report data.
        
        Args:
            config: Report configuration
            
        Returns:
            Compliance data dictionary
        """
        # Placeholder for compliance analysis
        return {
            'compliance_status': 'Compliance status overview',
            'audit_findings': 'Audit results and findings',
            'remediation_actions': 'Required remediation actions'
        }
    
    def _generate_custom_data(self, config: ReportConfig) -> Dict[str, Any]:
        """
        Generate custom report data.
        
        Args:
            config: Report configuration
            
        Returns:
            Custom data dictionary
        """
        # Placeholder for custom analysis
        return {
            'custom_metrics': 'Custom metrics and calculations',
            'ad_hoc_analysis': 'Ad-hoc analysis results',
            'special_insights': 'Special insights and findings'
        }
    
    def _apply_filters(self, sfr_qs, bouygues_qs, filters: Dict[str, Any]) -> Tuple:
        """
        Apply filters to querysets.
        
        Args:
            sfr_qs: SFR analytics queryset
            bouygues_qs: Bouygues analytics queryset
            filters: Filters to apply
            
        Returns:
            Tuple of filtered querysets
        """
        # Apply campaign filter
        if 'campaign' in filters:
            campaign_filter = Q(campaign_id=filters['campaign'])
            sfr_qs = sfr_qs.filter(campaign_filter)
            bouygues_qs = bouygues_qs.filter(campaign_filter)
        
        # Apply channel filter
        if 'channel' in filters:
            channel_filter = Q(channel_id=filters['channel'])
            sfr_qs = sfr_qs.filter(channel_filter)
            bouygues_qs = bouygues_qs.filter(channel_filter)
        
        # Apply provider filter
        if 'provider' in filters:
            if filters['provider'] == 'sfr':
                bouygues_qs = bouygues_qs.none()
            elif filters['provider'] == 'bouygues':
                sfr_qs = sfr_qs.none()
        
        return sfr_qs, bouygues_qs
    
    def _get_daily_breakdown(self, sfr_qs, bouygues_qs, config: ReportConfig) -> List[Dict[str, Any]]:
        """
        Get daily breakdown of analytics data.
        
        Args:
            sfr_qs: SFR analytics queryset
            bouygues_qs: Bouygues analytics queryset
            config: Report configuration
            
        Returns:
            List of daily breakdown data
        """
        daily_data = []
        current_date = config.start_date
        
        while current_date <= config.end_date:
            sfr_count = sfr_qs.filter(created_at__date=current_date).count()
            bouygues_count = bouygues_qs.filter(created_at__date=current_date).count()
            
            daily_data.append({
                'date': current_date.isoformat(),
                'sfr_impressions': sfr_count,
                'bouygues_impressions': bouygues_count,
                'total_impressions': sfr_count + bouygues_count
            })
            
            current_date += timedelta(days=1)
        
        return daily_data
    
    def _get_campaign_performance(self, config: ReportConfig) -> List[Dict[str, Any]]:
        """
        Get campaign performance data.
        
        Args:
            config: Report configuration
            
        Returns:
            List of campaign performance data
        """
        # Placeholder for campaign performance analysis
        return []
    
    def _get_channel_performance(self, config: ReportConfig) -> List[Dict[str, Any]]:
        """
        Get channel performance data.
        
        Args:
            config: Report configuration
            
        Returns:
            List of channel performance data
        """
        # Placeholder for channel performance analysis
        return []
    
    def _get_provider_comparison(self, sfr_qs, bouygues_qs) -> Dict[str, Any]:
        """
        Get provider comparison data.
        
        Args:
            sfr_qs: SFR analytics queryset
            bouygues_qs: Bouygues analytics queryset
            
        Returns:
            Provider comparison data
        """
        return {
            'sfr': {
                'total_impressions': sfr_qs.count(),
                'percentage': 0.0  # Would calculate actual percentage
            },
            'bouygues': {
                'total_impressions': bouygues_qs.count(),
                'percentage': 0.0  # Would calculate actual percentage
            }
        }
    
    def _create_report_file(self, config: ReportConfig, data: Dict[str, Any], options: Dict[str, Any]) -> str:
        """
        Create the actual report file.
        
        Args:
            config: Report configuration
            data: Report data
            options: Command options
            
        Returns:
            Path to created file
        """
        # Generate filename
        filename = self._generate_filename(config, options)
        
        # Determine output directory
        output_dir = options.get('output_dir', self.temp_dir)
        file_path = os.path.join(output_dir, filename)
        
        # Create file based on format
        if config.format == ExportFormat.PDF:
            self._create_pdf_report(file_path, config, data)
        elif config.format == ExportFormat.EXCEL:
            self._create_excel_report(file_path, config, data)
        elif config.format == ExportFormat.CSV:
            self._create_csv_report(file_path, config, data)
        elif config.format == ExportFormat.JSON:
            self._create_json_report(file_path, config, data)
        elif config.format == ExportFormat.HTML:
            self._create_html_report(file_path, config, data)
        else:
            raise ExportFailedException(f"Unsupported format: {config.format}")
        
        return file_path
    
    def _generate_filename(self, config: ReportConfig, options: Dict[str, Any]) -> str:
        """
        Generate filename for the report.
        
        Args:
            config: Report configuration
            options: Command options
            
        Returns:
            Generated filename
        """
        if options.get('filename'):
            return options['filename']
        
        # Generate default filename
        date_str = f"{config.start_date}_{config.end_date}"
        if config.start_date == config.end_date:
            date_str = config.start_date.isoformat()
        
        filename = f"analytics_{config.report_type.value}_{date_str}.{config.format.value}"
        return filename
    
    def _create_pdf_report(self, file_path: str, config: ReportConfig, data: Dict[str, Any]) -> None:
        """
        Create PDF report.
        
        Args:
            file_path: Output file path
            config: Report configuration
            data: Report data
        """
        # Placeholder for PDF generation
        with open(file_path, 'w') as f:
            f.write(f"PDF Report: {config.report_type.value}\n")
            f.write(f"Data: {data}\n")
    
    def _create_excel_report(self, file_path: str, config: ReportConfig, data: Dict[str, Any]) -> None:
        """
        Create Excel report.
        
        Args:
            file_path: Output file path
            config: Report configuration
            data: Report data
        """
        # Placeholder for Excel generation
        with open(file_path, 'w') as f:
            f.write(f"Excel Report: {config.report_type.value}\n")
            f.write(f"Data: {data}\n")
    
    def _create_csv_report(self, file_path: str, config: ReportConfig, data: Dict[str, Any]) -> None:
        """
        Create CSV report.
        
        Args:
            file_path: Output file path
            config: Report configuration
            data: Report data
        """
        # Placeholder for CSV generation
        with open(file_path, 'w') as f:
            f.write(f"CSV Report: {config.report_type.value}\n")
            f.write(f"Data: {data}\n")
    
    def _create_json_report(self, file_path: str, config: ReportConfig, data: Dict[str, Any]) -> None:
        """
        Create JSON report.
        
        Args:
            file_path: Output file path
            config: Report configuration
            data: Report data
        """
        import json
        
        report_data = {
            'report_type': config.report_type.value,
            'period': config.period.value,
            'date_range': {
                'start': config.start_date.isoformat(),
                'end': config.end_date.isoformat()
            },
            'generated_at': timezone.now().isoformat(),
            'data': data
        }
        
        with open(file_path, 'w') as f:
            json.dump(report_data, f, indent=2, default=str)
    
    def _create_html_report(self, file_path: str, config: ReportConfig, data: Dict[str, Any]) -> None:
        """
        Create HTML report.
        
        Args:
            file_path: Output file path
            config: Report configuration
            data: Report data
        """
        # Placeholder for HTML generation
        with open(file_path, 'w') as f:
            f.write(f"<html><body><h1>HTML Report: {config.report_type.value}</h1>")
            f.write(f"<p>Data: {data}</p></body></html>")
    
    def _create_report_metadata(self, config: ReportConfig, file_path: str, data: Dict[str, Any], start_time: datetime) -> ReportMetadata:
        """
        Create metadata for the generated report.
        
        Args:
            config: Report configuration
            file_path: Path to generated file
            data: Report data
            start_time: Generation start time
            
        Returns:
            Report metadata
        """
        end_time = timezone.now()
        generation_time = (end_time - start_time).total_seconds()
        
        # Get file size
        file_size = os.path.getsize(file_path) if os.path.exists(file_path) else 0
        
        # Count records
        record_count = self._count_records(data)
        
        # Generate report ID
        report_id = f"{config.report_type.value}_{config.start_date}_{config.end_date}_{int(end_time.timestamp())}"
        
        return ReportMetadata(
            report_id=report_id,
            title=f"{config.report_type.value.title()} Report",
            description=f"{config.report_type.value.title()} report for {config.start_date} to {config.end_date}",
            generated_at=end_time,
            file_path=file_path,
            file_size=file_size,
            record_count=record_count,
            generation_time=generation_time,
            config=config
        )
    
    def _count_records(self, data: Dict[str, Any]) -> int:
        """
        Count records in report data.
        
        Args:
            data: Report data
            
        Returns:
            Number of records
        """
        # Simple record counting logic
        if 'summary' in data and 'total_impressions' in data['summary']:
            return data['summary']['total_impressions']
        return 0
    
    def _email_report(self, metadata: ReportMetadata, config: ReportConfig) -> None:
        """
        Email the generated report.
        
        Args:
            metadata: Report metadata
            config: Report configuration
        """
        try:
            subject = f"Analytics Report: {metadata.title}"
            
            # Create email body
            body = f"""
            Analytics Report Generated
            
            Report Type: {config.report_type.value.title()}
            Period: {config.period.value.title()}
            Date Range: {config.start_date} to {config.end_date}
            Format: {config.format.value.upper()}
            
            Records: {metadata.record_count:,}
            File Size: {metadata.file_size:,} bytes
            Generation Time: {metadata.generation_time:.2f} seconds
            
            Please find the report attached.
            """
            
            # Create email
            email = EmailMessage(
                subject=subject,
                body=body,
                from_email=settings.DEFAULT_FROM_EMAIL,
                to=config.recipients
            )
            
            # Attach report file
            with open(metadata.file_path, 'rb') as f:
                email.attach(
                    os.path.basename(metadata.file_path),
                    f.read(),
                    'application/octet-stream'
                )
            
            # Send email
            email.send()
            
            self.stdout.write(
                self.style.SUCCESS(
                    f"Report emailed to {', '.join(config.recipients)}"
                )
            )
            
        except Exception as e:
            logger.error(f"Failed to email report: {e}", exc_info=True)
            self.stdout.write(
                self.style.ERROR(f"Failed to email report: {e}")
            )
    
    def _send_notifications(self, options: Dict[str, Any]) -> None:
        """
        Send completion notifications.
        
        Args:
            options: Command options
        """
        try:
            notification_data = {
                'command': 'generate_analytics_reports',
                'reports_generated': len(self.generated_reports),
                'reports': [
                    {
                        'type': metadata.config.report_type.value,
                        'file_path': metadata.file_path,
                        'file_size': metadata.file_size,
                        'record_count': metadata.record_count,
                        'generation_time': metadata.generation_time
                    }
                    for metadata in self.generated_reports
                ],
                'timestamp': timezone.now().isoformat()
            }
            
            send_notification(
                'analytics_reports_generated',
                notification_data
            )
            
        except Exception as e:
            logger.error(f"Failed to send notification: {e}")
    
    def _display_summary(self) -> None:
        """
        Display generation summary.
        """
        self.stdout.write("\n" + "=" * 50)
        self.stdout.write(self.style.SUCCESS("REPORT GENERATION SUMMARY"))
        self.stdout.write("=" * 50)
        
        self.stdout.write(f"Reports generated: {len(self.generated_reports)}")
        
        total_size = sum(metadata.file_size for metadata in self.generated_reports)
        total_records = sum(metadata.record_count for metadata in self.generated_reports)
        total_time = sum(metadata.generation_time for metadata in self.generated_reports)
        
        self.stdout.write(f"Total file size: {total_size:,} bytes")
        self.stdout.write(f"Total records: {total_records:,}")
        self.stdout.write(f"Total generation time: {total_time:.2f} seconds")
        
        if self.generated_reports:
            self.stdout.write("\nGenerated Reports:")
            for metadata in self.generated_reports:
                self.stdout.write(
                    f"  - {metadata.title}: {metadata.file_path} "
                    f"({metadata.file_size:,} bytes, {metadata.record_count:,} records)"
                )
        
        self.stdout.write("=" * 50)
    
    def _cleanup_temp_files(self) -> None:
        """
        Clean up temporary files.
        """
        if self.temp_dir and os.path.exists(self.temp_dir):
            try:
                import shutil
                shutil.rmtree(self.temp_dir)
            except Exception as e:
                logger.warning(f"Failed to cleanup temp directory: {e}")
    
    def _handle_command_error(self, error: Exception) -> None:
        """
        Handle command errors.
        
        Args:
            error: Exception that occurred
        """
        error_msg = f"Report generation failed: {error}"
        self.stdout.write(self.style.ERROR(error_msg))
        
        logger.error(
            error_msg,
            extra={
                'reports_generated': len(self.generated_reports),
                'temp_dir': self.temp_dir
            },
            exc_info=True
        )