<?php

namespace App\Http\Controllers;

use App\Models\Mentorship\Assignment as MentorshipAssignment;
use App\Models\SmsMessage;
use App\Models\SmsTemplate;
use App\Models\TrainingRegistration;
use App\Services\SmsCommunicationService;
use App\Http\Requests\SmsRequest;
use Illuminate\Http\Request;

class SmsController extends Controller
{
    public function __construct(
        protected SmsCommunicationService $smsService
    ) {}

    /**
     * Display SMS dashboard.
     */
    public function index(Request $request)
    {
        abort_unless(auth()->user()->can('view sms'), 403);

        $filters = $request->only(['status', 'search', 'date_from', 'date_to', 'sort_by', 'sort_order', 'per_page']);
        $messages = $this->smsService->getHistory(auth()->id(), $filters);
        $statistics = $this->smsService->getStatistics();
        $templates = $this->smsService->getTemplates();

        return view('sms.index', compact('messages', 'statistics', 'templates'));
    }

    /**
     * Show compose form.
     */
    public function create()
    {
        abort_unless(auth()->user()->can('create sms'), 403);

        $templates = $this->smsService->getTemplates();
        $availableRoles = $this->smsService->getAvailableRecipientRoles(auth()->user());

        return view('sms.compose', compact('templates', 'availableRoles'));
    }

    /**
     * Send SMS.
     */
    public function store(SmsRequest $request)
    {
        abort_unless(auth()->user()->can('create sms'), 403);

        // Server-side recipient validation based on sender role
        $user = auth()->user();
        $recipientIds = $request->input('recipients', []);

        if (!$user->hasAnyRole(['Super Manager', 'Manager']) && is_array($recipientIds) && count($recipientIds) > 0) {
            if ($user->hasRole('Trainers')) {
                // Trainers can only SMS trainees registered in sessions they train
                $allowedIds = TrainingRegistration::whereHas('session.trainers', function ($q) use ($user) {
                    $q->where('trainer_id', $user->id);
                })->pluck('user_id')->toArray();
                $invalid = array_diff($recipientIds, $allowedIds);
                if (!empty($invalid)) {
                    return back()->withInput()
                        ->with('error', 'You can only send SMS to your registered trainees.');
                }
            } elseif ($user->hasRole('Mentor')) {
                // Mentors can only SMS their assigned mentees
                $allowedIds = MentorshipAssignment::where('mentor_id', $user->id)
                    ->pluck('mentee_id')
                    ->toArray();
                $invalid = array_diff($recipientIds, $allowedIds);
                if (!empty($invalid)) {
                    return back()->withInput()
                        ->with('error', 'You can only send SMS to your assigned mentees.');
                }
            }
        }

        try {
            $message = $this->smsService->sendSms(
                auth()->id(),
                $request->input('recipients'),
                $request->input('message'),
                $request->only(['template_id', 'scheduled_at', 'sender_id_name', 'recipient_type', 'target_role'])
            );

            return redirect()
                ->route('sms.show', $message)
                ->with('success', 'SMS sent successfully!');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Failed to send SMS: ' . $e->getMessage());
        }
    }

    /**
     * Show SMS details.
     */
    public function show(SmsMessage $sms)
    {
        abort_unless(auth()->user()->can('view sms'), 403);
        abort_unless($this->canViewMessage($sms), 403);

        $sms->load(['sender', 'template']);

        return view('sms.show', compact('sms'));
    }

    /**
     * Show SMS history.
     */
    public function history(Request $request)
    {
        abort_unless(auth()->user()->can('view sms'), 403);

        $filters = $request->only(['status', 'search', 'date_from', 'date_to', 'sort_by', 'sort_order', 'per_page']);
        $messages = $this->smsService->getHistory(auth()->id(), $filters);

        return view('sms.history', compact('messages'));
    }

    /**
     * Delete SMS.
     */
    public function destroy(SmsMessage $sms)
    {
        abort_unless(auth()->user()->can('delete sms'), 403);

        try {
            $this->smsService->deleteMessage($sms->id, auth()->id());
            return redirect()
                ->route('sms.index')
                ->with('success', 'SMS deleted successfully!');
        } catch (\Exception $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    /**
     * Display templates.
     */
    public function templates()
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        $templates = SmsTemplate::with('creator')->latest()->paginate(15);

        return view('sms.templates', compact('templates'));
    }

    /**
     * Show create template form.
     */
    public function createTemplate()
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        return view('sms.template-form', ['template' => null]);
    }

    /**
     * Store a new template.
     */
    public function storeTemplate(Request $request)
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        $validated = $request->validate([
            'name'    => ['required', 'string', 'max:191'],
            'content' => ['required', 'string', 'max:1600'],
        ]);

        SmsTemplate::create([
            'name'       => $validated['name'],
            'slug'       => \Illuminate\Support\Str::slug($validated['name']),
            'content'    => $validated['content'],
            'is_active'  => true,
            'created_by' => auth()->id(),
        ]);

        return redirect()->route('sms.templates')->with('success', 'Template created successfully!');
    }

    /**
     * Show edit template form.
     */
    public function editTemplate(SmsTemplate $template)
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        return view('sms.template-form', compact('template'));
    }

    /**
     * Update a template.
     */
    public function updateTemplate(Request $request, SmsTemplate $template)
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        $validated = $request->validate([
            'name'    => ['required', 'string', 'max:191'],
            'content' => ['required', 'string', 'max:1600'],
        ]);

        $template->update([
            'name'    => $validated['name'],
            'slug'    => \Illuminate\Support\Str::slug($validated['name']),
            'content' => $validated['content'],
        ]);

        return redirect()->route('sms.templates')->with('success', 'Template updated successfully!');
    }

    /**
     * Delete a template.
     */
    public function destroyTemplate(SmsTemplate $template)
    {
        abort_unless(auth()->user()->can('manage sms templates'), 403);

        $template->delete();

        return redirect()->route('sms.templates')->with('success', 'Template deleted successfully!');
    }

    /**
     * Get users by role (AJAX).
     */
    public function getUsersByRole(string $role)
    {
        abort_unless(auth()->user()->can('create sms'), 403);

        $users = $this->smsService->getUsersByRole($role);

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

    /**
     * Check if user can view message.
     */
    protected function canViewMessage(SmsMessage $message): bool
    {
        $user = auth()->user();

        if ($user->hasAnyRole(['Super Manager', 'Manager'])) {
            return true;
        }

        return $message->sender_id === $user->id;
    }
}
