"""
PM4MKB Batch Conformance Analyzer Module
=========================================
Analyzes multiple process cases to identify systematic deviations.
"""

import pandas as pd
import numpy as np
from datetime import datetime
from collections import defaultdict, Counter
import json
import webbrowser
import os
from typing import Dict, List, Optional, Any

from pm4mkb.visualization_v2 import ConformanceAnalyzer, ProcessStandard


class BatchConformanceAnalyzer:
    """
    Analyzes multiple process cases to identify systematic deviations and patterns.
    """
    
    def __init__(self):
        """Initialize the batch analyzer with a real ConformanceAnalyzer instance."""
        self.single_analyzer = ConformanceAnalyzer()
        self.results = None
    
    def _parse_timestamp(self, timestamp_value):
        """Обработка различных форматов времени.
        
        Args:
            timestamp_value: Значение временной метки (строка или datetime)
            
        Returns:
            pd.Timestamp или None при ошибке
        """
        if pd.isna(timestamp_value):
            return None
            
        # If already datetime, return as is
        if isinstance(timestamp_value, pd.Timestamp):
            return timestamp_value
            
        # Try multiple date formats
        date_formats = [
            "%d/%m/%Y %H:%M",
            "%d/%m/%Y %H:%M:%S", 
            "%Y-%m-%d %H:%M:%S",
            "%d.%m.%Y %H:%M:%S",
            "%d.%m.%Y %H:%M",
            "%Y/%m/%d %H:%M:%S",
            "%Y-%m-%d",
            "%d/%m/%Y"
        ]
        
        for fmt in date_formats:
            try:
                return pd.to_datetime(timestamp_value, format=fmt)
            except:
                continue
        
        # Last resort - let pandas try to figure it out
        try:
            return pd.to_datetime(timestamp_value)
        except:
            print(f"Не удалось разобрать временную метку: {timestamp_value}")
            return None
    
    def _generate_paginated_table(self, data, table_id, headers=None, page_size=50):
        """Generate HTML table with pagination."""
        if not data:
            return "<p>Нет данных для отображения</p>"
            
        if headers is None:
            headers = list(data[0].keys()) if data else []
            
        rows_html = ""
        for i, row in enumerate(data):
            style = 'display: none;' if i >= page_size else ''
            rows_html += f'<tr class="data-row" style="{style}">'
            for h in headers:
                val = row.get(h, '')
                if isinstance(val, float):
                    val = f"{val:.1f}"
                rows_html += f'<td>{val}</td>'
            rows_html += '</tr>'
        
        return f"""
        <div class="table-container">
            <div class="pagination-controls">
                <button onclick="prevPage('{table_id}')">← Назад</button>
                <span id="{table_id}-info">Страница 1 из {len(data)//page_size + 1}</span>
                <button onclick="nextPage('{table_id}')">Вперёд →</button>
            </div>
            <table id="{table_id}" class="styled-table" data-page="0" data-size="{page_size}">
                <thead><tr>{''.join(f"<th>{h}</th>" for h in headers)}</tr></thead>
                <tbody>{rows_html}</tbody>
            </table>
        </div>
        <script>
        function nextPage(id) {{
            const table = document.getElementById(id);
            const rows = table.querySelectorAll('tbody tr');
            const size = parseInt(table.dataset.size);
            let page = parseInt(table.dataset.page);
            const maxPage = Math.floor(rows.length / size);
            
            if (page < maxPage) {{
                page++;
                table.dataset.page = page;
                updateTableDisplay(id, page, size);
            }}
        }}
        
        function prevPage(id) {{
            const table = document.getElementById(id);
            let page = parseInt(table.dataset.page);
            const size = parseInt(table.dataset.size);
            
            if (page > 0) {{
                page--;
                table.dataset.page = page;
                updateTableDisplay(id, page, size);
            }}
        }}
        
        function updateTableDisplay(id, page, size) {{
            const table = document.getElementById(id);
            const rows = table.querySelectorAll('tbody tr');
            const start = page * size;
            const end = start + size;
            
            rows.forEach((row, i) => {{
                row.style.display = (i >= start && i < end) ? '' : 'none';
            }});
            
            document.getElementById(id + '-info').textContent = 
                'Страница ' + (page + 1) + ' из ' + (Math.floor(rows.length / size) + 1);
        }}
        </script>
        """
    
    def analyze_batch(self,
        filepath: str,
        case_col: str,
        activity_col: str,
        timestamp_col: str,
        standard: ProcessStandard,
        conformance_threshold: float = 70.0,
        conformance_thresholds: Optional[Dict[str, float]] = None,
        resource_col: Optional[str] = None,
        output_path: str = "batch_analysis.html",
        show: bool = True
    ) -> Dict[str, Any]:
        """
        Analyze multiple cases against a process standard.
        """
        
        # Handle configurable thresholds
        if conformance_thresholds is None:
            conformance_thresholds = {
                'excellent': 90,
                'good': 70,
                'problematic': 50
            }
        
        print(f"\n{'='*60}")
        print(f"PM4MKB Batch Conformance Analysis")
        print(f"{'='*60}\n")
        
        # Load data
        print(f"📂 Loading data from {filepath}...")
        df = self._load_data(filepath)
        print(f"✓ Loaded {len(df)} events")
        
        # Validate columns
        required_cols = [case_col, activity_col, timestamp_col]
        missing_cols = [col for col in required_cols if col not in df.columns]
        if missing_cols:
            raise ValueError(f"Missing required columns: {missing_cols}")
        
        # Convert timestamp to datetime using flexible parser
        if not pd.api.types.is_datetime64_any_dtype(df[timestamp_col]):
            df[timestamp_col] = df[timestamp_col].apply(self._parse_timestamp)
        
        # Get unique cases
        cases = df[case_col].unique()
        total_cases = len(cases)
        print(f"📊 Found {total_cases} unique cases")
        print(f"🎯 Conformance threshold: {conformance_threshold}%\n")
        
        # Analyze each case using REAL ConformanceAnalyzer
        print("🔍 Analyzing cases with ConformanceAnalyzer...")
        case_results = []
        
        for idx, case_id in enumerate(cases):
            # Progress indicator
            if (idx + 1) % 10 == 0 or (idx + 1) == total_cases:
                print(f"  Прогресс: {idx+1}/{total_cases} ({(idx+1)*100//total_cases}%)")
            
            # Get case data
            case_data = df[df[case_col] == case_id].sort_values(timestamp_col)
            
            # Analyze using REAL ConformanceAnalyzer
            try:
                self.single_analyzer.analyze(
                    filepath,
                    case_col=case_col,
                    activity_col=activity_col,
                    timestamp_col=timestamp_col,
                    case_id=str(case_id),
                    standard=standard,
                    show=False
                )
                
                # Extract REAL results from the analyzer
                if hasattr(self.single_analyzer, 'last_analysis') and self.single_analyzer.last_analysis:
                    analysis = self.single_analyzer.last_analysis
                    
                    # Extract conformance score
                    conformance_score = analysis.get('conformance_level', 0.0)
                    
                    # Extract validation details
                    validation = analysis.get('validation', {})
                    category_counts = analysis.get('category_counts', {})
                    edge_categories = analysis.get('edge_categories', {})
                    
                    # Build deviations list from validation data
                    deviations = []
                    
                    # Check for forbidden activities
                    forbidden = validation.get('forbidden_found', [])
                    for activity in forbidden:
                        deviations.append({
                            'type': 'forbidden_activity',
                            'activity': activity,
                            'severity': 'high'
                        })
                    
                    # Check for missing required activities
                    missing = validation.get('missing_required', [])
                    for activity in missing:
                        deviations.append({
                            'type': 'missing_activity',
                            'activity': activity,
                            'severity': 'high'
                        })
                    
                    # Check for deviation edges
                    for edge_key, category in edge_categories.items():
                        if category == 'deviation':
                            if edge_key.startswith('e_'):
                                edge_name = edge_key[2:]
                                parts = edge_name.rsplit('_', 1)
                                if len(parts) == 2:
                                    from_act, to_act = parts
                                    deviations.append({
                                        'type': 'wrong_sequence',
                                        'from': from_act,
                                        'to': to_act,
                                        'severity': 'medium'
                                    })
                    
                    result = {
                        'case_id': case_id,
                        'conformance_score': conformance_score,
                        'deviations': deviations,
                        'num_activities': len(case_data),
                        'start_time': case_data[timestamp_col].min(),
                        'end_time': case_data[timestamp_col].max(),
                        'duration': (case_data[timestamp_col].max() - case_data[timestamp_col].min()).total_seconds() / 3600,
                        'is_conformant': conformance_score >= conformance_threshold,
                        'category_counts': category_counts
                    }
                    
                    if resource_col and resource_col in df.columns:
                        result['resources'] = case_data[resource_col].unique().tolist()
                    
                    case_results.append(result)
                    
            except Exception as e:
                print(f"\nWarning: Error analyzing case {case_id}: {e}")
                continue
        
        print("\n✓ Analysis complete!\n")
        
        if not case_results:
            raise ValueError("No cases were successfully analyzed.")
        
        # Aggregate results
        aggregated = self._aggregate_results(case_results, conformance_threshold, df, resource_col)
        
        # Generate HTML dashboard with pagination for large tables
        print(f"📝 Generating dashboard...")
        html_content = self._generate_dashboard(aggregated, standard, conformance_threshold, conformance_thresholds)
        
        # Save HTML
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(html_content)
        print(f"✓ Dashboard saved to {output_path}")
        
        # Display summary
        self._print_summary(aggregated, conformance_threshold)
        
        # Open in browser
        if show:
            print(f"\n🌐 Opening dashboard in browser...")
            webbrowser.open('file://' + os.path.abspath(output_path))
        
        self.results = aggregated
        return aggregated
    
    def _load_data(self, filepath: str) -> pd.DataFrame:
        """Load data from Excel or CSV file."""
        if filepath.endswith('.xlsx') or filepath.endswith('.xls'):
            return pd.read_excel(filepath)
        elif filepath.endswith('.csv'):
            return pd.read_csv(filepath)
        else:
            raise ValueError("Unsupported file format. Use .xlsx, .xls, or .csv")
    
    def _aggregate_results(
        self, 
        case_results: List[Dict], 
        threshold: float,
        df: pd.DataFrame = None,
        resource_col: str = None
    ) -> Dict[str, Any]:
        """Aggregate individual case results into summary statistics."""
        
        df_results = pd.DataFrame(case_results)
        
        # Basic statistics
        total_cases = len(case_results)
        avg_conformance = df_results['conformance_score'].mean()
        problem_cases = df_results[df_results['conformance_score'] < threshold]
        num_problem_cases = len(problem_cases)
        
        # Conformance distribution
        conformance_bins = [0, 50, 70, 85, 100]
        conformance_labels = ['Низкая (<50%)', 'Удовл. (50-70%)', 'Средн. (70-85%)', 'Высокая (85-100%)']
        df_results['conformance_category'] = pd.cut(
            df_results['conformance_score'],
            bins=conformance_bins,
            labels=conformance_labels,
            include_lowest=True
        )
        distribution = df_results['conformance_category'].value_counts().to_dict()
        
        # Collect all deviations
        all_deviations = []
        for result in case_results:
            if 'deviations' in result and result['deviations']:
                for dev in result['deviations']:
                    dev_copy = dev.copy()
                    dev_copy['case_id'] = result['case_id']
                    dev_copy['conformance_score'] = result['conformance_score']
                    all_deviations.append(dev_copy)
        
        # Deviation patterns
        deviation_patterns = self._analyze_deviation_patterns(all_deviations)
        
        # Temporal analysis
        temporal_analysis = self._analyze_temporal_trends(df_results)
        
        # Activity-level statistics
        activity_stats = self._calculate_activity_stats(all_deviations)
        
        # Resource performance analysis
        resource_stats = None
        if df is not None and resource_col and resource_col in df.columns:
            resource_stats = self._analyze_resource_performance(df_results, df, resource_col)
        
        return {
            'total_cases': total_cases,
            'avg_conformance': avg_conformance,
            'num_problem_cases': num_problem_cases,
            'problem_percentage': (num_problem_cases / total_cases * 100) if total_cases > 0 else 0,
            'distribution': distribution,
            'deviation_patterns': deviation_patterns,
            'temporal_analysis': temporal_analysis,
            'activity_stats': activity_stats,
            'resource_stats': resource_stats,
            'case_results': case_results,
            'problem_cases': problem_cases.to_dict('records'),
            'min_conformance': df_results['conformance_score'].min(),
            'max_conformance': df_results['conformance_score'].max(),
            'median_conformance': df_results['conformance_score'].median()
        }
    
    def _analyze_deviation_patterns(self, deviations: List[Dict]) -> List[Dict]:
        """Identify most common deviation patterns."""
        if not deviations:
            return []
        
        deviation_counter = Counter()
        deviation_details = defaultdict(list)
        
        for dev in deviations:
            dev_type = dev.get('type', 'unknown')
            deviation_counter[dev_type] += 1
            deviation_details[dev_type].append(dev)
        
        patterns = []
        total_deviations = len(deviations)
        
        for dev_type, count in deviation_counter.most_common(10):
            percentage = (count / total_deviations * 100) if total_deviations > 0 else 0
            
            severities = [d.get('severity', 'unknown') for d in deviation_details[dev_type]]
            severity_dist = Counter(severities)
            
            patterns.append({
                'type': dev_type,
                'count': count,
                'percentage': percentage,
                'severity_distribution': dict(severity_dist),
                'cases_affected': len(set(d['case_id'] for d in deviation_details[dev_type]))
            })
        
        return patterns
    
    def _analyze_temporal_trends(self, df_results: pd.DataFrame) -> Dict:
        """Analyze conformance trends over time."""
        if 'start_time' not in df_results.columns or df_results['start_time'].isna().all():
            return {'available': False}
        
        df_results = df_results.sort_values('start_time')
        df_results['date'] = pd.to_datetime(df_results['start_time']).dt.date
        daily_avg = df_results.groupby('date')['conformance_score'].mean()
        
        if len(daily_avg) < 2:
            return {'available': False}
        
        return {
            'available': True,
            'daily_average': {str(k): float(v) for k, v in daily_avg.to_dict().items()},
            'trend_direction': 'improving' if daily_avg.iloc[-1] > daily_avg.iloc[0] else 'declining'
        }
    
    def _calculate_activity_stats(self, deviations: List[Dict]) -> Dict:
        """Calculate statistics per activity."""
        activity_issues = defaultdict(lambda: defaultdict(int))
        
        for dev in deviations:
            dev_type = dev.get('type', 'unknown')
            activity = dev.get('activity') or dev.get('from')
            
            if activity:
                activity_issues[activity][dev_type] += 1
        
        return dict(activity_issues)
    
    def _analyze_resource_performance(
        self, 
        df_results: pd.DataFrame,
        df: pd.DataFrame,
        resource_col: str
    ) -> Dict:
        """Analyze performance by resource/operator."""
        resource_performance = []
        
        for result in df_results.to_dict('records'):
            if 'resources' in result and result['resources']:
                for resource in result['resources']:
                    resource_performance.append({
                        'resource': resource,
                        'case_id': result['case_id'],
                        'conformance': result['conformance_score']
                    })
        
        if not resource_performance:
            return {'available': False}
        
        df_perf = pd.DataFrame(resource_performance)
        resource_stats = df_perf.groupby('resource').agg({
            'case_id': 'count',
            'conformance': ['mean', 'min', 'max']
        }).round(1)
        
        resource_stats.columns = ['cases', 'avg_conformance', 'min_conformance', 'max_conformance']
        resource_stats = resource_stats.sort_values('avg_conformance', ascending=False)
        
        return {
            'available': True,
            'stats': resource_stats.to_dict('index')
        }
    
    def _print_summary(self, results: Dict, threshold: float):
        """Print analysis summary to console."""
        print(f"\n{'='*60}")
        print(f"ANALYSIS SUMMARY")
        print(f"{'='*60}")
        print(f"Total Cases Analyzed:     {results['total_cases']}")
        print(f"Average Conformance:      {results['avg_conformance']:.1f}%")
        print(f"Median Conformance:       {results['median_conformance']:.1f}%")
        print(f"Conformance Range:        {results['min_conformance']:.1f}% - {results['max_conformance']:.1f}%")
        print(f"\nProblem Cases (< {threshold}%): {results['num_problem_cases']} ({results['problem_percentage']:.1f}%)")
        
        if results['deviation_patterns']:
            print(f"\nTop 3 Deviation Types:")
            for i, pattern in enumerate(results['deviation_patterns'][:3], 1):
                print(f"  {i}. {pattern['type'].replace('_', ' ').title()}: {pattern['count']} occurrences ({pattern['percentage']:.1f}%)")
        
        print(f"{'='*60}\n")
    
    def _generate_dashboard(
        self, 
        results: Dict, 
        standard: ProcessStandard,
        threshold: float,
        conformance_thresholds: Dict[str, float]
    ) -> str:
        """Generate HTML dashboard with visualizations and pagination."""
        
        conformance_scores = [r['conformance_score'] for r in results['case_results']]
        
        # Temporal data
        temporal_data = []
        if results['temporal_analysis']['available']:
            for date, score in results['temporal_analysis']['daily_average'].items():
                temporal_data.append({'date': str(date), 'score': round(score, 2)})
        
        top_issues = results['deviation_patterns'][:10]
        problem_cases = sorted(results['problem_cases'], key=lambda x: x['conformance_score'])
        
        # Generate paginated table for problem cases if many
        if len(problem_cases) > 50:
            problem_cases_html = self._generate_paginated_table(
                problem_cases[:200],  # Limit to top 200
                'problem-cases-table',
                headers=['case_id', 'conformance_score', 'num_activities', 'duration']
            )
        else:
            # Regular table for small datasets
            problem_cases_html = f'''
            <table>
                <thead>
                    <tr>
                        <th>ID кейса</th>
                        <th>Конформность</th>
                        <th>Активностей</th>
                        <th>Длительность (ч)</th>
                        <th>Отклонений</th>
                    </tr>
                </thead>
                <tbody>
                    {''.join([f"""<tr>
                        <td><strong>{case["case_id"]}</strong></td>
                        <td>
                            {case["conformance_score"]:.1f}%
                            <div class="progress-bar">
                                <div class="progress-fill" style="width: {case["conformance_score"]}%;"></div>
                            </div>
                        </td>
                        <td>{case["num_activities"]}</td>
                        <td>{case["duration"]:.1f}</td>
                        <td>{len(case.get("deviations", []))}</td>
                    </tr>""" for case in problem_cases[:20]]) if problem_cases else '<tr><td colspan="5" style="text-align: center; color: #27ae60;">🎉 Проблемных кейсов не найдено!</td></tr>'}
                </tbody>
            </table>
            '''
        
        # Temporal chart JS
        temporal_chart_js = ''
        temporal_chart_html = ''
        if results['temporal_analysis']['available']:
            temporal_chart_html = '''
            <div class="section">
                <h2 class="section-title">Динамика конформности</h2>
                <div class="chart-container">
                    <canvas id="temporalChart"></canvas>
                </div>
            </div>'''
            
            temporal_chart_js = f'''
        const ctx2 = document.getElementById('temporalChart').getContext('2d');
        const temporalData = {json.dumps(temporal_data)};
        new Chart(ctx2, {{
            type: 'line',
            data: {{
                labels: temporalData.map(d => d.date),
                datasets: [{{
                    label: 'Средняя конформность',
                    data: temporalData.map(d => d.score),
                    borderColor: '#667eea',
                    backgroundColor: 'rgba(102, 126, 234, 0.1)',
                    fill: true,
                    tension: 0.4
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                scales: {{ y: {{ min: 0, max: 100 }} }}
            }}
        }});'''
        
        # Resource performance section
        resource_section = ''
        if results.get('resource_stats') and results['resource_stats']['available']:
            resource_rows = ''
            for resource, stats in results['resource_stats']['stats'].items():
                status_class = 'success' if stats['avg_conformance'] >= conformance_thresholds['excellent'] else 'warning' if stats['avg_conformance'] >= conformance_thresholds['good'] else 'danger'
                resource_rows += f'''
                <tr>
                    <td><strong>{resource}</strong></td>
                    <td><span class="badge badge-{status_class}">{stats['avg_conformance']:.1f}%</span></td>
                    <td>{stats['cases']}</td>
                    <td>{stats['min_conformance']:.1f}%</td>
                    <td>{stats['max_conformance']:.1f}%</td>
                </tr>'''
            
            resource_section = f'''
            <div class="section">
                <h2 class="section-title">Производительность сотрудников</h2>
                <table>
                    <thead>
                        <tr>
                            <th>Сотрудник</th>
                            <th>Средняя конформность</th>
                            <th>Кол-во кейсов</th>
                            <th>Мин</th>
                            <th>Макс</th>
                        </tr>
                    </thead>
                    <tbody>
                        {resource_rows}
                    </tbody>
                </table>
            </div>'''
        
        standard_name = getattr(standard, 'name', 'Стандарт процесса')
        
        html_template = f'''<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PM4MKB - Батч-анализ конформности</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f0f2f5; }}
        
        #header {{
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            padding: 15px 25px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            display: flex;
            align-items: center;
            justify-content: space-between;
            color: white;
        }}
        
        .header-left {{
            display: flex;
            align-items: center;
            gap: 15px;
        }}
        
        .header-logo {{
            height: 35px;
            filter: brightness(0) invert(1);
        }}
        
        .header-title {{
            font-size: 22px;
            font-weight: 600;
            color: white;
        }}
        
        .container {{ max-width: 1400px; margin: 20px auto; padding: 20px; }}
        
        .summary-cards {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }}
        
        .card {{
            background: white;
            padding: 25px;
            border-radius: 10px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            border-left: 5px solid #667eea;
        }}
        
        .card.success {{ border-left-color: #27ae60; }}
        .card.warning {{ border-left-color: #f39c12; }}
        .card.danger {{ border-left-color: #e74c3c; }}
        
        .card-title {{
            font-size: 12px;
            color: #6c757d;
            text-transform: uppercase;
            letter-spacing: 1px;
            margin-bottom: 10px;
        }}
        
        .card-value {{
            font-size: 36px;
            font-weight: bold;
            color: #1f2937;
        }}
        
        .card-subtitle {{
            font-size: 14px;
            color: #9ca3af;
            margin-top: 5px;
        }}
        
        .section {{
            background: white;
            padding: 25px;
            border-radius: 10px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }}
        
        .section-title {{
            font-size: 20px;
            margin-bottom: 20px;
            color: #1f2937;
            border-bottom: 2px solid #667eea;
            padding-bottom: 10px;
        }}
        
        .chart-container {{
            position: relative;
            height: 300px;
            margin: 20px 0;
        }}
        
        table {{
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }}
        
        th, td {{
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #e5e7eb;
        }}
        
        th {{
            background: #f8f9fa;
            font-weight: 600;
            color: #495057;
            text-transform: uppercase;
            font-size: 12px;
        }}
        
        tr:hover {{ background: #f9fafb; }}
        
        .badge {{
            display: inline-block;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 12px;
            font-weight: 600;
        }}
        
        .badge-high, .badge-danger {{ background: #fee2e2; color: #991b1b; }}
        .badge-medium, .badge-warning {{ background: #fef3c7; color: #92400e; }}
        .badge-low, .badge-success {{ background: #dcfce7; color: #15803d; }}
        
        .progress-bar {{
            height: 8px;
            background: #e5e7eb;
            border-radius: 4px;
            overflow: hidden;
            margin-top: 8px;
        }}
        
        .progress-fill {{
            height: 100%;
            background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
        }}
        
        .pagination-controls {{
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 15px;
            margin: 20px 0;
        }}
        
        .pagination-controls button {{
            padding: 8px 16px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }}
        
        .pagination-controls button:hover {{
            background: #5a67d8;
        }}
        
        .footer-branding {{
            text-align: center;
            padding: 20px;
            color: #888;
            font-size: 11px;
            border-top: 1px solid #e0e0e0;
            margin-top: 20px;
        }}
    </style>
</head>
<body>
    <div id="header">
        <div class="header-left">
            <img src="data:image/png;base64, " alt="PM4MKB" class="header-logo" />
            <div class="header-title">Scope-анализ конформности процессов</div>
        </div>
        <div style="background: rgba(255,255,255,0.2); color: white; padding: 8px 18px; border-radius: 20px; font-size: 14px; font-weight: 600;">
            {standard_name}
        </div>
    </div>
    
    <div class="container">
        <div class="summary-cards">
            <div class="card">
                <div class="card-title">Всего кейсов</div>
                <div class="card-value">{results['total_cases']}</div>
                <div class="card-subtitle">Проанализировано</div>
            </div>
            
            <div class="card {'success' if results['avg_conformance'] >= conformance_thresholds['excellent'] else 'warning' if results['avg_conformance'] >= conformance_thresholds['good'] else 'danger'}">
                <div class="card-title">Средняя конформность</div>
                <div class="card-value">{results['avg_conformance']:.1f}%</div>
                <div class="card-subtitle">Медиана: {results['median_conformance']:.1f}%</div>
            </div>
            
            <div class="card {'danger' if results['problem_percentage'] > 20 else 'warning' if results['problem_percentage'] > 10 else 'success'}">
                <div class="card-title">Проблемные кейсы</div>
                <div class="card-value">{results['num_problem_cases']}</div>
                <div class="card-subtitle">{results['problem_percentage']:.1f}% ниже {threshold}%</div>
            </div>
            
            <div class="card">
                <div class="card-title">Диапазон</div>
                <div class="card-value">{results['max_conformance'] - results['min_conformance']:.0f}</div>
                <div class="card-subtitle">{results['min_conformance']:.0f}% - {results['max_conformance']:.0f}%</div>
            </div>
        </div>
        
        <div class="section">
            <h2 class="section-title">Распределение конформности</h2>
            <div class="chart-container">
                <canvas id="distributionChart"></canvas>
            </div>
        </div>
        
        {temporal_chart_html}
        
        {resource_section}
        
        <div class="section">
            <h2 class="section-title">Топ отклонений</h2>
            <table>
                <thead>
                    <tr>
                        <th>№</th>
                        <th>Тип отклонения</th>
                        <th>Количество</th>
                        <th>% от общего</th>
                        <th>Затронуто кейсов</th>
                        <th>Серьезность</th>
                    </tr>
                </thead>
                <tbody>
                    {''.join([f'''<tr>
                        <td><strong>#{i+1}</strong></td>
                        <td>{issue["type"].replace("_", " ").replace("wrong sequence", "неверная последовательность").replace("forbidden activity", "запрещённая активность").replace("missing activity", "пропущена активность")}</td>
                        <td>{issue["count"]}</td>
                        <td>{issue["percentage"]:.1f}%</td>
                        <td>{issue["cases_affected"]}</td>
                        <td>{"".join([f'<span class="badge badge-{sev}">{sev}</span> ' for sev in issue["severity_distribution"].keys()])}</td>
                    </tr>''' for i, issue in enumerate(top_issues)])}
                </tbody>
            </table>
        </div>
        
        <div class="section">
            <h2 class="section-title">Проблемные кейсы (ниже {threshold}%)</h2>
            {problem_cases_html}
        </div>
        
        <div class="footer-branding">
            Powered by PM4MKB © 2025
        </div>
    </div>
    
    <script>
        const ctx1 = document.getElementById('distributionChart').getContext('2d');
        const conformanceScores = {json.dumps(conformance_scores)};
        new Chart(ctx1, {{
            type: 'bar',
            data: {{
                labels: ['0-{conformance_thresholds['problematic']}%', '{conformance_thresholds['problematic']}-{conformance_thresholds['good']}%', '{conformance_thresholds['good']}-{conformance_thresholds['excellent']}%', '{conformance_thresholds['excellent']}-100%'],
                datasets: [{{
                    label: 'Количество кейсов',
                    data: [
                        conformanceScores.filter(s => s < {conformance_thresholds['problematic']}).length,
                        conformanceScores.filter(s => s >= {conformance_thresholds['problematic']} && s < {conformance_thresholds['good']}).length,
                        conformanceScores.filter(s => s >= {conformance_thresholds['good']} && s < {conformance_thresholds['excellent']}).length,
                        conformanceScores.filter(s => s >= {conformance_thresholds['excellent']}).length
                    ],
                    backgroundColor: ['#ef4444', '#f59e0b', '#3b82f6', '#10b981'],
                    borderRadius: 8
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                plugins: {{ legend: {{ display: false }} }},
                scales: {{ y: {{ beginAtZero: true, ticks: {{ stepSize: 1 }} }} }}
            }}
        }});
        
        {temporal_chart_js}
    </script>
</body>
</html>'''
        
        return html_template


__all__ = ['BatchConformanceAnalyzer']