<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Services\MicrosoftGraph\SmartSyncService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Exception;

class SmartSyncTestController extends Controller
{
    private $smartSyncService;

    public function __construct(SmartSyncService $smartSyncService)
    {
        $this->smartSyncService = $smartSyncService;
    }

    /**
     * Trigger Smart Sync and return results for browser viewing
     */
    public function triggerSync(Request $request)
    {
        $startTime = microtime(true);
        $results = [];
        $errors = [];
        $logs = [];

        try {
            Log::info('[SmartSyncTest] Starting manual Smart Sync trigger from web interface');

            // Execute the smart sync
            $syncResults = $this->smartSyncService->processAllPendingChanges();

            $endTime = microtime(true);
            $duration = round($endTime - $startTime, 2);

            Log::info('[SmartSyncTest] Smart Sync completed', [
                'duration_seconds' => $duration,
                'results' => $syncResults
            ]);

            // Prepare response data
            $results = [
                'success' => true,
                'duration' => $duration,
                'sync_results' => $syncResults,
                'timestamp' => now()->format('Y-m-d H:i:s'),
                'triggered_by' => 'Web Interface'
            ];

        } catch (Exception $e) {
            $endTime = microtime(true);
            $duration = round($endTime - $startTime, 2);

            Log::error('[SmartSyncTest] Smart Sync failed', [
                'duration_seconds' => $duration,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            $errors[] = [
                'message' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            ];

            $results = [
                'success' => false,
                'duration' => $duration,
                'error' => $e->getMessage(),
                'timestamp' => now()->format('Y-m-d H:i:s'),
                'triggered_by' => 'Web Interface'
            ];
        }

        // Get recent log entries related to Smart Sync
        $logs = $this->getRecentSyncLogs();

        // Return HTML view with results
        return view('admin.smart-sync-test', [
            'results' => $results,
            'errors' => $errors,
            'logs' => $logs,
            'timestamp' => now()->format('Y-m-d H:i:s')
        ]);
    }

    /**
     * Get recent Smart Sync related log entries
     */
    private function getRecentSyncLogs()
    {
        $logs = [];
        $logFile = storage_path('logs/laravel-' . date('Y-m-d') . '.log');

        if (file_exists($logFile)) {
            try {
                $content = file_get_contents($logFile);
                $lines = explode("\n", $content);

                // Get last 100 lines and filter for Smart Sync related entries
                $recentLines = array_slice($lines, -100);

                foreach ($recentLines as $line) {
                    if (strpos($line, 'SmartSync') !== false ||
                        strpos($line, 'MsgraphPendingChange') !== false ||
                        strpos($line, 'MsgraphModelChange') !== false ||
                        strpos($line, 'MicrosoftGraph') !== false) {
                        $logs[] = $line;
                    }
                }

                // Get last 20 relevant entries
                $logs = array_slice($logs, -20);

            } catch (Exception $e) {
                $logs[] = 'Error reading log file: ' . $e->getMessage();
            }
        } else {
            $logs[] = 'Log file not found: ' . $logFile;
        }

        return $logs;
    }

    /**
     * Show sync status page
     */
    public function showStatus()
    {
        $pendingChanges = \App\Models\MsgraphPendingChange::where('processed', false)
            ->orderBy('priority', 'desc')
            ->orderBy('created_at', 'asc')
            ->get();

        $modelChanges = \App\Models\MsgraphModelChange::where('processed', false)
            ->orderBy('priority', 'desc')
            ->orderBy('created_at', 'asc')
            ->get();

        return view('admin.smart-sync-status', [
            'pending_changes' => $pendingChanges,
            'model_changes' => $modelChanges,
            'timestamp' => now()->format('Y-m-d H:i:s')
        ]);
    }

    /**
     * Show traditional sync interface with options
     */
    public function triggerTraditionalSync(Request $request)
    {
        return view('admin.msgraph-sync-interface', [
            'timestamp' => now()->format('Y-m-d H:i:s')
        ]);
    }

    /**
     * Execute traditional Microsoft Graph sync with options
     */
    public function executeTraditionalSync(Request $request)
    {
        $startTime = microtime(true);
        $results = [];
        $errors = [];
        $logs = [];

        try {
            Log::info('[TraditionalSyncTest] Starting manual Traditional Sync from web interface', [
                'options' => $request->all()
            ]);

            // Get the traditional sync service
            $traditionalSyncService = app(\App\Services\MicrosoftGraphSyncService::class);
            $traditionalSyncService->initialize();

            // Parse options from request
            $dryRun = $request->boolean('dry_run', false);
            $operation = $request->input('operation', 'all');
            $extraOptions = $request->input('extra_options', []);

            // Execute based on operation type
            switch ($operation) {
                case 'test_connection':
                    $syncResults = $traditionalSyncService->testConnection();
                    break;

                case 'contact_folders':
                    $syncResults = $traditionalSyncService->syncContactFolders($dryRun);
                    break;

                case 'contacts':
                    $syncResults = $traditionalSyncService->syncContacts($dryRun);
                    break;

                case 'list_folders':
                    $withContactCount = in_array('with_contact_count', $extraOptions);
                    $syncResults = $traditionalSyncService->listContactFolders(null, $withContactCount);
                    break;

                case 'list_all_contacts':
                    $syncResults = $traditionalSyncService->listAllContacts();
                    break;

                case 'sync_folder_ids':
                    $syncResults = $traditionalSyncService->syncExistingFolderIds($dryRun);
                    break;

                case 'clear_contacts':
                    $syncResults = $traditionalSyncService->clearAllContacts($dryRun);
                    break;

                case 'delete_folders':
                    if (!in_array('confirm_deletion', $extraOptions) && !$dryRun) {
                        throw new Exception('Deletion operations require confirmation');
                    }
                    $syncResults = $traditionalSyncService->deleteAllContactFolders($dryRun);
                    break;

                case 'delete_everything':
                    if (!in_array('confirm_deletion', $extraOptions) && !$dryRun) {
                        throw new Exception('Deletion operations require confirmation');
                    }
                    $syncResults = $traditionalSyncService->deleteAllContactFoldersAndContacts($dryRun);
                    break;

                case 'cleanup_database':
                    $syncResults = $this->cleanupDatabase($dryRun);
                    break;

                case 'test_contact_folder':
                    $folderName = $request->input('test_folder_name', 'Web-Test-Folder');
                    $syncResults = $traditionalSyncService->createTestContactFolder($folderName);

                    // Auto-delete test folder if creation was successful
                    if ($syncResults['success'] && isset($syncResults['folder_id'])) {
                        $deleteResults = $traditionalSyncService->deleteTestContactFolder($syncResults['folder_id']);
                        $syncResults['auto_deleted'] = $deleteResults['success'];
                        $syncResults['delete_message'] = $deleteResults['success']
                            ? 'Test folder automatically deleted'
                            : 'Failed to auto-delete: ' . ($deleteResults['error'] ?? 'Unknown error');
                    }
                    break;

                default: // 'all' - full clean slate sync
                    $syncResults = $traditionalSyncService->syncAll($dryRun);
                    break;
            }

            $endTime = microtime(true);
            $duration = round($endTime - $startTime, 2);

            Log::info('[TraditionalSyncTest] Traditional Sync completed', [
                'operation' => $operation,
                'duration_seconds' => $duration,
                'results' => $syncResults,
                'dry_run' => $dryRun
            ]);

            // Prepare response data
            $results = [
                'success' => true,
                'duration' => $duration,
                'operation' => $operation,
                'dry_run' => $dryRun,
                'sync_results' => $syncResults,
                'timestamp' => now()->format('Y-m-d H:i:s'),
                'triggered_by' => 'Web Interface (Traditional Sync)',
                'extra_options' => $extraOptions
            ];

        } catch (Exception $e) {
            $endTime = microtime(true);
            $duration = round($endTime - $startTime, 2);

            Log::error('[TraditionalSyncTest] Traditional Sync failed', [
                'operation' => $request->input('operation', 'unknown'),
                'duration_seconds' => $duration,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            $errors[] = [
                'message' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            ];

            $results = [
                'success' => false,
                'duration' => $duration,
                'operation' => $request->input('operation', 'unknown'),
                'dry_run' => $request->boolean('dry_run', false),
                'error' => $e->getMessage(),
                'timestamp' => now()->format('Y-m-d H:i:s'),
                'triggered_by' => 'Web Interface (Traditional Sync)'
            ];
        }

        // Get recent log entries related to Traditional Sync
        $logs = $this->getRecentTraditionalSyncLogs();

        // Return HTML view with results
        return view('admin.msgraph-sync-results', [
            'results' => $results,
            'errors' => $errors,
            'logs' => $logs,
            'timestamp' => now()->format('Y-m-d H:i:s')
        ]);
    }

    /**
     * Get recent Traditional Sync related log entries
     */
    private function getRecentTraditionalSyncLogs()
    {
        $logs = [];
        $logFile = storage_path('logs/laravel-' . date('Y-m-d') . '.log');

        if (file_exists($logFile)) {
            try {
                $content = file_get_contents($logFile);
                $lines = explode("\n", $content);

                // Get last 150 lines and filter for Traditional Sync related entries
                $recentLines = array_slice($lines, -150);

                foreach ($recentLines as $line) {
                    if (strpos($line, 'TraditionalSyncTest') !== false ||
                        strpos($line, 'MicrosoftGraphSyncService') !== false ||
                        strpos($line, 'Microsoft Graph') !== false ||
                        strpos($line, 'msgraph') !== false) {
                        $logs[] = $line;
                    }
                }

                // Get last 25 relevant entries
                $logs = array_slice($logs, -25);

            } catch (Exception $e) {
                $logs[] = 'Error reading log file: ' . $e->getMessage();
            }
        } else {
            $logs[] = 'Log file not found: ' . $logFile;
        }

        return $logs;
    }

    /**
     * Helper method for database cleanup
     */
    private function cleanupDatabase(bool $dryRun = false): array
    {
        $committeesCount = 0;
        $workgroupsCount = 0;

        if ($dryRun) {
            // Count what would be cleared
            $committeesCount = \App\Models\Committee::whereNotNull('ms_id')->count();
            $workgroupsCount = \App\Models\WorkGroup::whereNotNull('ms_id')->count();
        } else {
            // Actually clear the ms_id values
            $committeesCount = \App\Models\Committee::whereNotNull('ms_id')->update(['ms_id' => null]);
            $workgroupsCount = \App\Models\WorkGroup::whereNotNull('ms_id')->update(['ms_id' => null]);
        }

        return [
            'success' => true,
            'committees_cleared' => $committeesCount,
            'workgroups_cleared' => $workgroupsCount,
            'total_cleared' => $committeesCount + $workgroupsCount,
            'dry_run' => $dryRun
        ];
    }
}
