<?php

namespace Modules\MedPortal\Http\Controllers;

use Illuminate\Http\Request;
use Modules\MedPortal\Services\MessagingService;
use Modules\MedPortal\Support\ClinicBridge;

/**
 * Secure messaging inbox (staff side, SIFA Phase 8). Thread list + open a thread
 * + reply as staff. Guarded by mportal.messages.
 */
class MessageController extends MedPortalBaseController
{
    public function index(MessagingService $messaging)
    {
        $this->guard('mportal.messages');

        $businessId = $this->businessId();
        $threads = $messaging->threadsForBusiness($businessId);

        $patientNames = ClinicBridge::patientNames(
            $businessId,
            $threads->pluck('patient_id')->unique()->map(fn ($id) => (int) $id)->all()
        );

        return view('medportal::messages.index', [
            'threads'      => $threads,
            'patientNames' => $patientNames,
        ]);
    }

    /** Open a single thread (returns a modal partial for the inbox). */
    public function show(string $threadId, MessagingService $messaging)
    {
        $this->guard('mportal.messages');

        $businessId = $this->businessId();
        $messages = $messaging->thread($businessId, $threadId);

        if ($messages->isEmpty()) {
            abort(404);
        }

        // Staff opened it → mark patient messages read.
        $messaging->markRead($businessId, $threadId, 'staff');

        $patientId = (int) $messages->first()->patient_id;

        return view('medportal::messages.thread', [
            'threadId'    => $threadId,
            'messages'    => $messages,
            'patientId'   => $patientId,
            'patientName' => ClinicBridge::patientName($businessId, $patientId),
        ]);
    }

    /** Staff reply into an existing thread. */
    public function reply(Request $request, MessagingService $messaging)
    {
        $this->guard('mportal.messages');

        $data = $this->validate($request, [
            'thread_id' => 'required|uuid',
            'body'      => 'required|string|max:5000',
        ]);

        try {
            $businessId = $this->businessId();

            // Resolve the thread's patient/contact from its first message.
            $first = $messaging->thread($businessId, $data['thread_id'])->first();
            if (! $first) {
                return $this->fail(__('medportal::lang.thread_not_found'));
            }

            $messaging->send(
                $businessId,
                (int) $first->patient_id,
                (int) $first->contact_id,
                'staff',
                (int) $this->userId(),
                $data['body'],
                $data['thread_id']
            );

            return $this->ok(__('medportal::lang.message_sent'));
        } catch (\Throwable $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    /** Staff start a new thread to a patient. */
    public function start(Request $request, MessagingService $messaging)
    {
        $this->guard('mportal.messages');

        $data = $this->validate($request, [
            'patient_id' => 'required|integer',
            'body'       => 'required|string|max:5000',
        ]);

        try {
            $businessId = $this->businessId();
            $patientId  = (int) $data['patient_id'];
            $contactId  = ClinicBridge::contactIdForPatient($businessId, $patientId);

            if (! $contactId) {
                return $this->fail(__('medportal::lang.patient_no_contact'));
            }

            $messaging->send(
                $businessId,
                $patientId,
                $contactId,
                'staff',
                (int) $this->userId(),
                $data['body']
            );

            return $this->ok(__('medportal::lang.message_sent'));
        } catch (\Throwable $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    /** Patient picker for the "new message" modal. */
    public function create()
    {
        $this->guard('mportal.messages');

        return view('medportal::messages.new', [
            'patients' => ClinicBridge::patientOptions($this->businessId()),
        ]);
    }
}
