<?php

namespace Modules\Bms\Http\Controllers;

use Illuminate\Http\Request;
use Modules\Bms\Entities\BmsBooking;
use Modules\Bms\Entities\BmsQcEvent;
use Modules\Bms\Entities\BmsQcInspection;
use Modules\Bms\Services\Contracts\MediaServiceContract;
use Modules\Bms\Services\Qc\QcService;

/**
 * P1 quality-control runner — the back-office counterpart of the bms-staff QC
 * card. It calls the SAME QcService the PWA uses (inspectionFor / record /
 * addVoice), so a P1 inspection behaves identically: pass/fail/na per item with
 * a default reason-code + note, a recorded voice memo, and an activity trail.
 */
class QcController extends BmsBaseController
{
    /** Inspection runner for a booking + stage. */
    public function run(Request $request, $id, QcService $qc)
    {
        $this->guard('bms.qc.view');
        $booking = BmsBooking::with('contact:id,name')->where('business_id', $this->businessId())->findOrFail($id);
        $stage = in_array($request->query('stage'), ['pre_event', 'post_event'], true) ? $request->query('stage') : 'pre_event';

        $inspection = $qc->inspectionFor($booking, $stage);

        return view('bms::qc.run', [
            'booking'    => $booking,
            'inspection' => $inspection,
            'stage'      => $stage,
            'reasons'    => $qc->reasons($this->businessId()),
            'events'     => $this->events($inspection),
            'canManage'  => auth()->user()->can('bms.qc.manage'),
        ]);
    }

    /** Record the inspection results (pass/fail/na + reason_code + note). */
    public function submit(Request $request, $id, QcService $qc)
    {
        $this->guard('bms.qc.manage');
        $inspection = BmsQcInspection::where('business_id', $this->businessId())->findOrFail($id);
        $data = $this->validate($request, [
            'items'               => 'required|array',
            'items.*.label'       => 'nullable|string',
            'items.*.label_ar'    => 'nullable|string',
            'items.*.status'      => 'nullable|in:pass,fail,na',
            'items.*.reason_code' => 'nullable|string|max:40',
            'items.*.note'        => 'nullable|string|max:500',
        ]);

        $qc->record($inspection, $data['items'], $this->userId());

        return redirect()->route('bms.qc.run', ['id' => $inspection->booking_id, 'stage' => $inspection->stage])
            ->with('status', __('bms::lang.qc_saved'));
    }

    /** Attach a recorded voice memo (MediaRecorder upload) to the inspection. */
    public function voice(Request $request, $id, QcService $qc)
    {
        $this->guard('bms.qc.manage');
        $inspection = BmsQcInspection::where('business_id', $this->businessId())->findOrFail($id);
        $this->validate($request, ['file' => 'required|file|max:20480']); // 20 MB

        $stored = app(MediaServiceContract::class)->store($this->businessId(), "qc/{$inspection->id}", $request->file('file'));
        $qc->addVoice($inspection, $stored['url'] ?: $stored['path'], $this->userId());

        return response()->json(['ok' => true]);
    }

    /** Activity trail (who started / submitted / recorded voice + when). */
    protected function events(BmsQcInspection $inspection): array
    {
        $events = BmsQcEvent::where('inspection_id', $inspection->id)->latest()->get();
        $users = \App\User::whereIn('id', $events->pluck('user_id')->filter())->get()->keyBy('id');

        return $events->map(fn ($e) => [
            'type'   => $e->type,
            'detail' => $e->detail,
            'user'   => optional($users->get($e->user_id))->first_name,
            'at'     => optional($e->created_at)->format('Y-m-d H:i'),
        ])->all();
    }
}
