<?php

namespace App\Http\Controllers;

use App\Models\EmailConfiguration;
use App\Models\EmailLog;
use App\Services\EmailConfigurationService as ConfigurationService;
use App\Services\EmailProvider;
use App\Services\EmailService;
use App\Http\Requests\EmailConfigurationRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\View\View;

/**
 * EmailConfigurationController
 * 
 * Controller for managing email configuration settings.
 * Provides CRUD operations, connection testing, and log viewing.
 * 
 * Permission Requirements:
 * - All methods require 'manage email configuration' permission
 * - Access is restricted to Super Manager role
 * 
 * @package App\Http\Controllers
 */
class EmailConfigurationController extends Controller
{
    /**
     * Configuration service instance.
     *
     * @var ConfigurationService
     */
    protected ConfigurationService $configService;

    /**
     * Email provider instance.
     *
     * @var EmailProvider
     */
    protected EmailProvider $emailProvider;

    /**
     * Email service instance.
     *
     * @var EmailService
     */
    protected EmailService $emailService;

    /**
     * Create a new controller instance.
     *
     * @param ConfigurationService $configService
     * @param EmailProvider $emailProvider
     * @param EmailService $emailService
     */
    public function __construct(
        ConfigurationService $configService,
        EmailProvider $emailProvider,
        EmailService $emailService
    ) {
        $this->configService = $configService;
        $this->emailProvider = $emailProvider;
        $this->emailService = $emailService;
    }

    /**
     * Display the email configuration dashboard.
     * Shows current configuration status and quick actions.
     *
     * @return View
     */
    public function index(): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Get current configuration status
        $status = $this->configService->getStatusSummary();
        $configuration = $this->configService->getConfiguration();

        // Get recent logs summary
        $recentLogs = EmailLog::orderBy('created_at', 'desc')
            ->limit(5)
            ->get();

        // Get log statistics
        $logStats = EmailLog::getStatistics();

        // Get recent activity
        $recentActivity = EmailLog::getRecentActivity(24);

        return view('config.email.index', compact(
            'status',
            'configuration',
            'recentLogs',
            'logStats',
            'recentActivity'
        ));
    }

    /**
     * Show the form for creating a new email configuration.
     *
     * @return View
     */
    public function create(): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Get encryption types for dropdowns
        $encryptionTypes = EmailProvider::getEncryptionTypes();
        $envConfig = $this->configService->getEnvironmentConfig();

        return view('config.email.form', compact(
            'encryptionTypes',
            'envConfig'
        ));
    }

    /**
     * Store a newly created email configuration.
     *
     * @param EmailConfigurationRequest $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(EmailConfigurationRequest $request)
    {
        // Permission check (also in request, but double-check)
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Get validated data
        $data = $request->getValidatedData();

        // Save configuration
        $configuration = $this->configService->saveConfiguration($data);

        return redirect()
            ->route('config.email.index')
            ->with('success', 'Email configuration saved successfully.');
    }

    /**
     * Show the form for editing the email configuration.
     *
     * @return View
     */
    public function edit(): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Get current configuration
        $configuration = $this->configService->getConfiguration();

        if (!$configuration) {
            return redirect()
                ->route('config.email.create')
                ->with('info', 'No configuration found. Please create a new configuration.');
        }

        // Get encryption types for dropdowns
        $encryptionTypes = EmailProvider::getEncryptionTypes();

        return view('config.email.form', compact(
            'configuration',
            'encryptionTypes'
        ));
    }

    /**
     * Update the email configuration.
     *
     * @param EmailConfigurationRequest $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(EmailConfigurationRequest $request)
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Get current configuration
        $configuration = $this->configService->getConfiguration();

        if (!$configuration) {
            return redirect()
                ->route('config.email.create')
                ->with('error', 'No configuration found to update.');
        }

        // Get validated data
        $data = $request->getValidatedData();

        // Update configuration
        $this->configService->updateConfiguration($configuration, $data);

        return redirect()
            ->route('config.email.index')
            ->with('success', 'Email configuration updated successfully.');
    }

    /**
     * Test SMTP or IMAP connection.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function testConnection(Request $request): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Validate request
        $request->validate([
            'type' => 'required|in:smtp,imap',
        ]);

        $type = $request->input('type');

        // Test connection based on type
        if ($type === 'smtp') {
            $result = $this->emailProvider->testSmtpConnection();
        } else {
            $result = $this->emailProvider->testImapConnection();
        }

        return response()->json($result);
    }

    /**
     * Display email logs.
     *
     * @param Request $request
     * @return View
     */
    public function logs(Request $request): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Build query with filters
        $query = EmailLog::orderBy('created_at', 'desc');

        // Filter by type
        if ($request->has('type') && $request->type !== 'all') {
            $query->ofType($request->type);
        }

        // Filter by status
        if ($request->has('status') && $request->status !== 'all') {
            $query->withStatus($request->status);
        }

        // Filter by date range
        if ($request->has('date_from')) {
            $query->where('created_at', '>=', $request->date_from);
        }
        if ($request->has('date_to')) {
            $query->where('created_at', '<=', $request->date_to . ' 23:59:59');
        }

        // Get paginated logs
        $logs = $query->paginate(20)->withQueryString();

        // Get statistics
        $statistics = EmailLog::getStatistics();

        // Get filter options
        $types = [
            'all' => 'All Types',
            'smtp_send' => 'SMTP Send',
            'imap_receive' => 'IMAP Receive',
            'test' => 'Connection Test',
        ];

        $statuses = [
            'all' => 'All Statuses',
            'success' => 'Success',
            'failed' => 'Failed',
        ];

        return view('config.email.logs', compact(
            'logs',
            'statistics',
            'types',
            'statuses'
        ));
    }

    /**
     * Display the documentation page.
     * Shows integration guide for developers.
     *
     * @return View
     */
    public function documentation(): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        return view('config.email.documentation');
    }

    /**
     * Delete the current configuration.
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy()
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        $configuration = $this->configService->getConfiguration();

        if (!$configuration) {
            return redirect()
                ->route('config.email.index')
                ->with('error', 'No configuration found to delete.');
        }

        $this->configService->deleteConfiguration($configuration);

        return redirect()
            ->route('config.email.index')
            ->with('success', 'Email configuration deleted successfully.');
    }

    /**
     * Send a test email (for configuration verification).
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function sendTestEmail(Request $request): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        // Validate request
        $request->validate([
            'email' => 'required|email|max:191',
        ]);

        $to = $request->input('email');
        $subject = 'Email Configuration Test';
        $body = '<h1>Test Email</h1><p>This is a test email from the Email Configuration module.</p><p>If you received this, your SMTP configuration is working correctly.</p>';

        // Send test email
        $result = $this->emailService->sendHtml($to, $subject, $body);

        return response()->json($result);
    }

    /**
     * Get configuration status via AJAX.
     *
     * @return JsonResponse
     */
    public function getStatus(): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        $status = $this->emailService->getStatus();

        return response()->json([
            'success' => true,
            'data' => $status,
        ]);
    }

    /**
     * Clear configuration cache.
     *
     * @return JsonResponse
     */
    public function clearCache(): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        $this->configService->clearCache();

        return response()->json([
            'success' => true,
            'message' => 'Configuration cache cleared successfully.',
        ]);
    }

    /**
     * Export logs as JSON.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function exportLogs(Request $request): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage email configuration'), 403);

        $query = EmailLog::orderBy('created_at', 'desc');

        // Apply same filters as logs page
        if ($request->has('type') && $request->type !== 'all') {
            $query->ofType($request->type);
        }
        if ($request->has('status') && $request->status !== 'all') {
            $query->withStatus($request->status);
        }

        // Limit export to 1000 records
        $logs = $query->limit(1000)->get();

        return response()->json([
            'success' => true,
            'count' => $logs->count(),
            'data' => $logs,
        ]);
    }
}
