<?php

namespace App\Http\Controllers;

use App\Http\Requests\SmsConfigurationRequest;
use App\Http\Requests\SmsTestRequest;
use App\Models\SmsConfiguration;
use App\Models\SmsLog;
use App\Services\SmsConfigurationService as ConfigurationService;
use App\Services\SMSProvider;
use App\Services\SMSService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;

/**
 * SmsConfigurationController
 * 
 * Controller for managing SMS configuration settings.
 * Handles CRUD operations, testing, logs, and documentation.
 * 
 * All methods require Super Manager role permission.
 * 
 * @package App\Http\Controllers
 */
class SmsConfigurationController extends Controller
{
    /**
     * Configuration service instance.
     *
     * @var ConfigurationService
     */
    protected ConfigurationService $configService;

    /**
     * SMS Provider instance.
     *
     * @var SMSProvider
     */
    protected SMSProvider $smsProvider;

    /**
     * SMS Service instance.
     *
     * @var SMSService
     */
    protected SMSService $smsService;

    /**
     * Create a new controller instance.
     *
     * @param ConfigurationService $configService
     * @param SMSProvider $smsProvider
     * @param SMSService $smsService
     */
    public function __construct(
        ConfigurationService $configService,
        SMSProvider $smsProvider,
        SMSService $smsService
    ) {
        $this->configService = $configService;
        $this->smsProvider = $smsProvider;
        $this->smsService = $smsService;
    }

    /**
     * Display the SMS configuration dashboard.
     * 
     * Shows current configuration status, statistics, and quick actions.
     *
     * @return View
     */
    public function index(): View
    {
        // Permission check - only Super Manager can access
        abort_unless(auth()->user()->can('manage sms configuration'), 403, 
            'Only Super Managers can access SMS configuration.');

        // Get configuration status
        $status = $this->configService->getStatus();
        
        // Get configuration if exists
        $configuration = $this->configService->getConfiguration();
        
        // Get recent logs (last 10)
        $recentLogs = SmsLog::with('user')
            ->latest()
            ->take(10)
            ->get();
        
        // Get statistics
        $statistics = $this->getStatistics();
        
        // Get API status
        $apiStatus = $this->smsProvider->checkApiStatus();

        return view('config.sms.index', compact(
            'status',
            'configuration',
            'recentLogs',
            'statistics',
            'apiStatus'
        ));
    }

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

        // Check if configuration already exists
        $existingConfig = $this->configService->getConfiguration();
        
        if ($existingConfig) {
            return redirect()
                ->route('config.sms.edit')
                ->with('info', 'Configuration already exists. You can edit it here.');
        }

        return view('config.sms.form', [
            'configuration' => null,
            'mode' => 'create',
        ]);
    }

    /**
     * Store a newly created SMS configuration.
     *
     * @param SmsConfigurationRequest $request
     * @return RedirectResponse
     */
    public function store(SmsConfigurationRequest $request): RedirectResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

        try {
            $configuration = $this->configService->saveConfiguration($request->validated());

            return redirect()
                ->route('config.sms.index')
                ->with('success', 'SMS configuration saved successfully!');

        } catch (\Exception $e) {
            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'Failed to save configuration: ' . $e->getMessage());
        }
    }

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

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

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

        return view('config.sms.form', [
            'configuration' => $configuration,
            'mode' => 'edit',
        ]);
    }

    /**
     * Update the SMS configuration.
     *
     * @param SmsConfigurationRequest $request
     * @return RedirectResponse
     */
    public function update(SmsConfigurationRequest $request): RedirectResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

        try {
            $configuration = $this->configService->saveConfiguration($request->validated());

            return redirect()
                ->route('config.sms.index')
                ->with('success', 'SMS configuration updated successfully!');

        } catch (\Exception $e) {
            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'Failed to update configuration: ' . $e->getMessage());
        }
    }

    /**
     * Test the SMS connection by sending a test message.
     *
     * @param SmsTestRequest $request
     * @return JsonResponse
     */
    public function testConnection(SmsTestRequest $request): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

        $testPhone = $request->input('test_phone');
        $testMessage = $request->input('test_message');

        try {
            $result = $this->smsProvider->testConnection($testPhone, $testMessage);

            if ($result['success']) {
                return response()->json([
                    'success' => true,
                    'message' => 'Test SMS sent successfully!',
                    'message_id' => $result['message_id'] ?? null,
                    'log_id' => $result['log_id'] ?? null,
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => $result['message'] ?? 'Failed to send test SMS',
                'error_code' => $result['error_code'] ?? null,
            ], 400);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An error occurred: ' . $e->getMessage(),
            ], 500);
        }
    }

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

        $query = SmsLog::with(['configuration', 'user']);

        // Filter by status
        if ($request->filled('status')) {
            $query->withStatus($request->status);
        }

        // Filter by date range
        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        // Search by recipient or message
        if ($request->filled('search')) {
            $query->search($request->search);
        }

        // Order by latest first
        $query->latest();

        // Paginate results
        $logs = $query->paginate(25)->appends($request->query());

        // Get statistics for the view
        $statistics = [
            'total' => SmsLog::count(),
            'sent' => SmsLog::sent()->count(),
            'failed' => SmsLog::failed()->count(),
            'pending' => SmsLog::pending()->count(),
            'today' => SmsLog::today()->count(),
            'this_month' => SmsLog::thisMonth()->count(),
        ];

        return view('config.sms.logs', compact('logs', 'statistics'));
    }

    /**
     * Display the SMS integration documentation.
     *
     * @return View
     */
    public function documentation(): View
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

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

    /**
     * Delete the SMS configuration.
     *
     * @return RedirectResponse
     */
    public function destroy(): RedirectResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

        try {
            $this->configService->deleteConfiguration();

            return redirect()
                ->route('config.sms.index')
                ->with('success', 'SMS configuration deleted successfully.');

        } catch (\Exception $e) {
            return redirect()
                ->back()
                ->with('error', 'Failed to delete configuration: ' . $e->getMessage());
        }
    }

    /**
     * Get SMS log details via AJAX.
     *
     * @param SmsLog $log
     * @return JsonResponse
     */
    public function getLogDetails(SmsLog $log): JsonResponse
    {
        // Permission check
        abort_unless(auth()->user()->can('manage sms configuration'), 403);

        $log->load(['configuration', 'user']);

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $log->id,
                'recipient' => $log->recipient,
                'message' => $log->message,
                'status' => $log->status,
                'status_color' => $log->getStatusColor(),
                'message_id' => $log->message_id,
                'error_message' => $log->error_message,
                'execution_time_ms' => $log->execution_time_ms,
                'cost' => $log->cost,
                'created_at' => $log->created_at->format('Y-m-d H:i:s'),
                'user' => $log->user?->name,
                'configuration' => $log->configuration ? [
                    'sender_id' => $log->configuration->sender_id,
                    'environment' => $log->configuration->environment,
                ] : null,
            ],
        ]);
    }

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

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

    /**
     * Calculate SMS statistics.
     *
     * @return array
     */
    protected function getStatistics(): array
    {
        return [
            'total_sent' => SmsLog::sent()->count(),
            'total_failed' => SmsLog::failed()->count(),
            'total_pending' => SmsLog::pending()->count(),
            'total_delivered' => SmsLog::delivered()->count(),
            'today_sent' => SmsLog::today()->sent()->count(),
            'today_failed' => SmsLog::today()->failed()->count(),
            'this_month_sent' => SmsLog::thisMonth()->sent()->count(),
            'total_cost' => SmsLog::sum('cost'),
        ];
    }
}
