#!/usr/bin/env python3
"""
Web UI for Vendor Report Generator

Provides a simple web interface for generating reports, viewing status, and managing configuration.
"""

import logging
import json
from pathlib import Path
from typing import Optional
from datetime import datetime

try:
    from flask import Flask, render_template_string, jsonify, request, send_from_directory, redirect, url_for
    from flask_cors import CORS
    FLASK_AVAILABLE = True
except ImportError:
    FLASK_AVAILABLE = False
    logging.warning("Flask not installed. Web UI features disabled.")

from config import load_config
from report_generator import generate_report
from sharepoint_downloader import download_from_sharepoint

logger = logging.getLogger(__name__)

app = None
config = None

# HTML Template for the Web UI
UI_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vendor Report Generator</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 12px;
            box-shadow: 0 10px 40px rgba(0,0,0,0.2);
            overflow: hidden;
        }
        
        header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        header p {
            opacity: 0.9;
            font-size: 1.1em;
        }
        
        .content {
            padding: 40px;
        }
        
        .section {
            margin-bottom: 40px;
            padding: 30px;
            background: #f9fafb;
            border-radius: 8px;
            border: 1px solid #e5e7eb;
        }
        
        .section h2 {
            color: #1e40af;
            margin-bottom: 20px;
            font-size: 1.5em;
        }
        
        .button-group {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
            margin-top: 20px;
        }
        
        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 6px;
            font-size: 1em;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s;
            text-decoration: none;
            display: inline-block;
        }
        
        .btn-primary {
            background: #2563eb;
            color: white;
        }
        
        .btn-primary:hover {
            background: #1d4ed8;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
        }
        
        .btn-success {
            background: #10b981;
            color: white;
        }
        
        .btn-success:hover {
            background: #059669;
        }
        
        .btn-secondary {
            background: #6b7280;
            color: white;
        }
        
        .btn-secondary:hover {
            background: #4b5563;
        }
        
        .btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            transform: none;
        }
        
        .status-card {
            background: white;
            padding: 20px;
            border-radius: 8px;
            border-left: 4px solid #2563eb;
            margin-bottom: 15px;
        }
        
        .status-card h3 {
            color: #374151;
            margin-bottom: 10px;
        }
        
        .status-card p {
            color: #6b7280;
            margin: 5px 0;
        }
        
        .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 8px;
        }
        
        .status-indicator.active {
            background: #10b981;
        }
        
        .status-indicator.inactive {
            background: #ef4444;
        }
        
        .loading {
            display: none;
            text-align: center;
            padding: 20px;
        }
        
        .loading.active {
            display: block;
        }
        
        .spinner {
            border: 4px solid #f3f4f6;
            border-top: 4px solid #2563eb;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 15px;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .alert {
            padding: 15px;
            border-radius: 6px;
            margin-bottom: 20px;
            display: none;
        }
        
        .alert.active {
            display: block;
        }
        
        .alert-success {
            background: #d1fae5;
            color: #065f46;
            border: 1px solid #10b981;
        }
        
        .alert-error {
            background: #fee2e2;
            color: #991b1b;
            border: 1px solid #ef4444;
        }
        
        .alert-info {
            background: #dbeafe;
            color: #1e40af;
            border: 1px solid #2563eb;
        }
        
        .report-list {
            list-style: none;
        }
        
        .report-item {
            background: white;
            padding: 15px;
            border-radius: 6px;
            margin-bottom: 10px;
            border: 1px solid #e5e7eb;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .report-item:hover {
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        
        .report-info {
            flex: 1;
        }
        
        .report-info strong {
            color: #1e40af;
            display: block;
            margin-bottom: 5px;
        }
        
        .report-info small {
            color: #6b7280;
        }
        
        .config-item {
            margin-bottom: 15px;
            padding: 15px;
            background: white;
            border-radius: 6px;
            border: 1px solid #e5e7eb;
        }
        
        .config-item label {
            display: block;
            font-weight: 600;
            color: #374151;
            margin-bottom: 5px;
        }
        
        .config-item .value {
            color: #6b7280;
            font-family: monospace;
        }
        
        .badge {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 0.85em;
            font-weight: 600;
        }
        
        .badge-enabled {
            background: #d1fae5;
            color: #065f46;
        }
        
        .badge-disabled {
            background: #fee2e2;
            color: #991b1b;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>📊 Vendor Report Generator</h1>
            <p>Generate comprehensive vendor punchlist reports from Excel files</p>
        </header>
        
        <div class="content">
            <div id="alert-container"></div>
            
            <!-- Update Data Section -->
            <div class="section">
                <h2>Update Data</h2>
                <p>Download the latest Excel files from SharePoint to update your local data.</p>
                
                <div class="button-group">
                    <button class="btn btn-success" onclick="updateFromSharePoint()">
                        Update Data from SharePoint
                    </button>
                </div>
                
                <div class="loading" id="loading-update">
                    <div class="spinner"></div>
                    <p>Downloading files from SharePoint... This may take a moment.</p>
                </div>
            </div>
            
            <!-- Generate Report Section -->
            <div class="section">
                <h2>Generate Report</h2>
                <p>Generate a new report from Excel files in the local reports directory.</p>
                
                <div class="button-group">
                    <button class="btn btn-primary" onclick="generateReport()">
                        Generate Report
                    </button>
                </div>
                
                <div class="loading" id="loading">
                    <div class="spinner"></div>
                    <p>Generating report... This may take a moment.</p>
                </div>
            </div>
            
            <!-- Status Section -->
            <div class="section">
                <h2>Service Status</h2>
                <div id="status-container">
                    <div class="status-card">
                        <h3>Loading status...</h3>
                    </div>
                </div>
            </div>
            
            <!-- Reports Section -->
            <div class="section">
                <h2>Generated Reports</h2>
                <div id="reports-container">
                    <p>Loading reports...</p>
                </div>
            </div>
            
            <!-- Configuration Section -->
            <div class="section">
                <h2>Configuration</h2>
                <div id="config-container">
                    <p>Loading configuration...</p>
                </div>
            </div>
        </div>
    </div>
    
    <script>
        // Update data from SharePoint
        async function updateFromSharePoint() {
            const loading = document.getElementById('loading-update');
            const alertContainer = document.getElementById('alert-container');
            
            loading.classList.add('active');
            alertContainer.innerHTML = '';
            
            try {
                const response = await fetch('/api/update-sharepoint', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    showAlert('success', `Successfully downloaded ${data.downloaded_count} file(s) from SharePoint!`);
                    loadStatus();
                } else {
                    showAlert('error', `Error: ${data.error || 'Failed to download from SharePoint'}`);
                }
            } catch (error) {
                showAlert('error', `Error: ${error.message}`);
            } finally {
                loading.classList.remove('active');
            }
        }
        
        // Generate report
        async function generateReport() {
            const loading = document.getElementById('loading');
            const alertContainer = document.getElementById('alert-container');
            
            loading.classList.add('active');
            alertContainer.innerHTML = '';
            
            try {
                const response = await fetch('/api/generate', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        download_from_sharepoint: false
                    })
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    showAlert('success', `Report generated successfully! Processed ${data.vendors_count || 0} vendors.`);
                    loadReports();
                    loadStatus();
                } else {
                    showAlert('error', `Error: ${data.error || 'Failed to generate report'}`);
                }
            } catch (error) {
                showAlert('error', `Error: ${error.message}`);
                console.error('Generate report error:', error);
            } finally {
                loading.classList.remove('active');
            }
        }
        
        // Load status
        async function loadStatus() {
            try {
                const response = await fetch('/api/status');
                const data = await response.json();
                
                const container = document.getElementById('status-container');
                container.innerHTML = `
                    <div class="status-card">
                        <h3>
                            <span class="status-indicator ${data.status === 'running' ? 'active' : 'inactive'}"></span>
                            Service Status: ${data.status}
                        </h3>
                        <p><strong>SharePoint:</strong> <span class="badge ${data.sharepoint_enabled ? 'badge-enabled' : 'badge-disabled'}">${data.sharepoint_enabled ? 'Enabled' : 'Disabled'}</span></p>
                        <p><strong>Reports Directory:</strong> ${data.reports_dir}</p>
                        <p><strong>Output Directory:</strong> ${data.output_dir}</p>
                    </div>
                `;
            } catch (error) {
                console.error('Failed to load status:', error);
            }
        }
        
        // Load reports
        async function loadReports() {
            try {
                const response = await fetch('/api/reports');
                const data = await response.json();
                
                const container = document.getElementById('reports-container');
                
                if (data.reports && data.reports.length > 0) {
                    const reportsList = data.reports.map(report => `
                        <div class="report-item">
                            <div class="report-info">
                                <strong>${report.name}</strong>
                                <small>Generated: ${report.generated_at} | Size: ${report.size}</small>
                            </div>
                            <div>
                                <a href="/reports/${report.name}" class="btn btn-primary" target="_blank">View HTML</a>
                                ${report.json_exists ? `<a href="/reports/${report.json_name}" class="btn btn-secondary" download>Download JSON</a>` : ''}
                            </div>
                        </div>
                    `).join('');
                    
                    container.innerHTML = `<ul class="report-list">${reportsList}</ul>`;
                } else {
                    container.innerHTML = '<p>No reports generated yet.</p>';
            } catch (error) {
                console.error('Failed to load reports:', error);
                document.getElementById('reports-container').innerHTML = '<p>Error loading reports.</p>';
            }
        }
        
        // Load configuration
        async function loadConfig() {
            try {
                const response = await fetch('/api/config');
                const config = await response.json();
                
                const container = document.getElementById('config-container');
                const configItems = Object.entries(config).map(([key, value]) => {
                    const displayValue = typeof value === 'boolean' 
                        ? `<span class="badge ${value ? 'badge-enabled' : 'badge-disabled'}">${value ? 'Enabled' : 'Disabled'}</span>`
                        : String(value || 'Not configured');
                    return `
                        <div class="config-item">
                            <label>${key.replace(/_/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase())}</label>
                            <div class="value">${displayValue}</div>
                        </div>
                    `;
                }).join('');
                
                container.innerHTML = configItems;
            } catch (error) {
                console.error('Failed to load config:', error);
                document.getElementById('config-container').innerHTML = '<p>Error loading configuration.</p>';
            }
        }
        
        // Show alert
        function showAlert(type, message) {
            const container = document.getElementById('alert-container');
            const alert = document.createElement('div');
            alert.className = `alert alert-${type} active`;
            alert.textContent = message;
            container.appendChild(alert);
            
            setTimeout(() => {
                alert.remove();
            }, 5000);
        }
        
        // Load data on page load
        window.addEventListener('DOMContentLoaded', () => {
            loadStatus();
            loadReports();
            loadConfig();
            
            // Refresh every 30 seconds
            setInterval(() => {
                loadStatus();
                loadReports();
            }, 30000);
        });
    </script>
</body>
</html>
"""


def create_app(config_path: Optional[str] = None):
    """Create and configure Flask app with Web UI."""
    global app, config
    
    if not FLASK_AVAILABLE:
        raise ImportError(
            "Flask is required for Web UI. "
            "Install it with: pip install flask flask-cors"
        )
    
    app = Flask(__name__)
    CORS(app)
    
    config = load_config(config_path)
    api_config = config.get('api', {})
    sharepoint_config = config.get('sharepoint', {})
    report_config = config.get('report', {})
    
    app.config['API_KEY'] = api_config.get('api_key')
    app.config['SHAREPOINT_CONFIG'] = sharepoint_config
    app.config['REPORT_CONFIG'] = report_config
    
    @app.route('/')
    def index():
        """Main web UI page."""
        return render_template_string(UI_TEMPLATE)
    
    @app.route('/api/update-sharepoint', methods=['POST'])
    def update_sharepoint_endpoint():
        """Download files from SharePoint."""
        api_key = app.config.get('API_KEY')
        if api_key:
            provided_key = request.headers.get('X-API-Key') or (request.json.get('api_key') if request.json else None)
            if provided_key != api_key:
                return jsonify({'error': 'Invalid API key'}), 401
        
        try:
            sp_config = app.config['SHAREPOINT_CONFIG']
            if not sp_config.get('enabled'):
                return jsonify({'error': 'SharePoint is not enabled in configuration'}), 400
            
            logger.info("Downloading files from SharePoint...")
            try:
                downloaded = download_from_sharepoint(
                    site_url=sp_config['site_url'],
                    folder_path=sp_config.get('folder_path'),
                    file_path=sp_config.get('file_path'),
                    local_dir=sp_config.get('local_dir', 'reports'),
                    tenant_id=sp_config.get('tenant_id'),
                    client_id=sp_config.get('client_id'),
                    client_secret=sp_config.get('client_secret'),
                    use_app_authentication=sp_config.get('use_app_authentication', True),
                    file_pattern=sp_config.get('file_pattern'),
                    overwrite=sp_config.get('overwrite', True)
                )
                logger.info(f"Downloaded {len(downloaded)} file(s) from SharePoint")
                return jsonify({
                    'status': 'success',
                    'message': f'Successfully downloaded {len(downloaded)} file(s) from SharePoint',
                    'downloaded_count': len(downloaded),
                    'files': downloaded
                })
            except Exception as e:
                logger.error(f"Failed to download from SharePoint: {e}", exc_info=True)
                return jsonify({'error': f'SharePoint download failed: {str(e)}'}), 500
                
        except Exception as e:
            logger.error(f"Error updating from SharePoint: {e}", exc_info=True)
            return jsonify({'error': f'Update failed: {str(e)}'}), 500
    
    @app.route('/api/generate', methods=['POST'])
    def generate_report_endpoint():
        """Generate report on demand."""
        api_key = app.config.get('API_KEY')
        if api_key:
            provided_key = request.headers.get('X-API-Key') or (request.json.get('api_key') if request.json else None)
            if provided_key != api_key:
                return jsonify({'error': 'Invalid API key'}), 401
        
        try:
            request_data = request.json or {}
            
            report_config = app.config['REPORT_CONFIG']
            reports_dir = request_data.get('reports_dir', report_config.get('reports_dir', 'reports'))
            output_file = request_data.get('output_file', 
                                          str(Path(report_config.get('output_dir', 'output')) / 'report.json'))
            
            # Check if reports directory exists and has files
            reports_path = Path(reports_dir)
            if not reports_path.exists():
                return jsonify({'error': f'Reports directory not found: {reports_dir}'}), 400
            
            excel_files = list(reports_path.glob('*.xlsx')) + list(reports_path.glob('*.xls'))
            if not excel_files:
                return jsonify({'error': f'No Excel files found in {reports_dir}. Please update data from SharePoint first.'}), 400
            
            logger.info(f"Generating report from {reports_dir} ({len(excel_files)} Excel file(s))...")
            report_data = generate_report(
                reports_dir=reports_dir,
                output_file=output_file,
                verbose=False
            )
            
            if report_data and report_data.get('vendors'):
                return jsonify({
                    'status': 'success',
                    'message': 'Report generated successfully',
                    'output_file': output_file,
                    'summary': report_data.get('summary', {}),
                    'vendors_count': len(report_data.get('vendors', []))
                })
            else:
                return jsonify({'error': 'Report generation failed - no data processed'}), 500
                
        except Exception as e:
            logger.error(f"Error generating report: {e}", exc_info=True)
            return jsonify({'error': f'Report generation failed: {str(e)}'}), 500
    
    @app.route('/api/status', methods=['GET'])
    def status():
        """Get service status."""
        return jsonify({
            'status': 'running',
            'sharepoint_enabled': app.config['SHAREPOINT_CONFIG'].get('enabled', False),
            'reports_dir': app.config['REPORT_CONFIG'].get('reports_dir', 'reports'),
            'output_dir': app.config['REPORT_CONFIG'].get('output_dir', 'output')
        })
    
    @app.route('/api/reports', methods=['GET'])
    def list_reports():
        """List generated reports."""
        output_dir = Path(app.config['REPORT_CONFIG'].get('output_dir', 'output'))
        reports = []
        
        if output_dir.exists():
            html_files = list(output_dir.glob('*.html'))
            for html_file in html_files:
                json_file = html_file.with_suffix('.json')
                reports.append({
                    'name': html_file.name,
                    'json_name': json_file.name if json_file.exists() else None,
                    'json_exists': json_file.exists(),
                    'generated_at': datetime.fromtimestamp(html_file.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S'),
                    'size': f"{html_file.stat().st_size / 1024:.1f} KB"
                })
        
        # Sort by modification time (newest first)
        reports.sort(key=lambda x: x['generated_at'], reverse=True)
        
        return jsonify({'reports': reports})
    
    @app.route('/api/config', methods=['GET'])
    def get_config():
        """Get configuration (safe, no secrets)."""
        return jsonify({
            'sharepoint_enabled': app.config['SHAREPOINT_CONFIG'].get('enabled', False),
            'sharepoint_site_url': app.config['SHAREPOINT_CONFIG'].get('site_url', 'Not configured'),
            'sharepoint_folder_path': app.config['SHAREPOINT_CONFIG'].get('folder_path', 'Not configured'),
            'reports_dir': app.config['REPORT_CONFIG'].get('reports_dir', 'reports'),
            'output_dir': app.config['REPORT_CONFIG'].get('output_dir', 'output')
        })
    
    @app.route('/reports/<filename>')
    def serve_report(filename):
        """Serve report files."""
        output_dir = Path(app.config['REPORT_CONFIG'].get('output_dir', 'output'))
        return send_from_directory(str(output_dir), filename)
    
    @app.route('/health', methods=['GET'])
    def health():
        """Health check."""
        return jsonify({'status': 'healthy', 'service': 'vendor-report-generator-ui'})
    
    return app


def run_server(config_path: Optional[str] = None, host: Optional[str] = None, port: Optional[int] = None):
    """Run the Web UI server."""
    app = create_app(config_path)
    
    api_config = config.get('api', {})
    server_host = host or api_config.get('host', '0.0.0.0')
    server_port = port or api_config.get('port', 8080)
    
    logger.info(f"Starting Web UI server on http://{server_host}:{server_port}")
    app.run(host=server_host, port=server_port, debug=False)


if __name__ == "__main__":
    import sys
    
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    config_path = sys.argv[1] if len(sys.argv) > 1 else None
    
    config = load_config(config_path)
    if not config.get('api', {}).get('enabled', False):
        logger.warning("API is disabled in configuration, but starting Web UI anyway...")
    
    run_server(config_path=config_path)

