<?php

namespace Modules\VrcPortalApi\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Vrc\Entities\VrcInspection;
use Modules\Vrc\Entities\VrcRepairOrder;
use Modules\Vrc\Entities\VrcRepairOrderLaborLog;
use Modules\Vrc\Entities\VrcRepairOrderService as RoLine;
use Modules\Vrc\Services\RepairOrder\RepairOrderService;

/**
 * VRC staff PWA: workshop board, job detail, line status, labor clock and DVI.
 * The authenticated ERP user is set by StaffApiAuth, so $user->can()/Gate work.
 */
class StaffController extends Controller
{
    public function __construct(protected RepairOrderService $orders)
    {
    }

    private function user(Request $request)
    {
        return $request->attributes->get('vrc_user') ?: auth()->user();
    }

    private function bid(Request $request): int
    {
        return (int) $this->user($request)->business_id;
    }

    public function me(Request $request): JsonResponse
    {
        $u = $this->user($request);
        return response()->json([
            'id' => $u->id, 'name' => trim($u->first_name . ' ' . ($u->last_name ?? '')) ?: $u->username,
            'username' => $u->username, 'business_id' => $u->business_id,
            'can' => [
                'manage_orders'      => $u->can('vrc.repair_order.manage'),
                'manage_inspections' => $u->can('vrc.inspection.manage'),
            ],
        ]);
    }

    public function summary(Request $request): JsonResponse
    {
        $bid = $this->bid($request);
        $uid = $this->user($request)->id;

        $open = VrcRepairOrder::where('business_id', $bid)
            ->whereNotIn('status', ['completed', 'cancelled'])->count();
        $myLines = RoLine::where('business_id', $bid)->where('assigned_technician_id', $uid)
            ->whereIn('status', ['pending', 'in_progress'])->count();
        $ready = VrcRepairOrder::where('business_id', $bid)->where('status', 'ready_for_pickup')->count();
        $awaitingParts = VrcRepairOrder::where('business_id', $bid)->where('status', 'awaiting_parts')->count();

        return response()->json([
            'open_orders'    => $open,
            'my_open_jobs'   => $myLines,
            'ready_pickup'   => $ready,
            'awaiting_parts' => $awaitingParts,
        ]);
    }

    public function board(Request $request): JsonResponse
    {
        $bid = $this->bid($request);
        $uid = $this->user($request)->id;
        $mine = $request->query('scope') === 'mine';

        $statuses = ['checked_in', 'awaiting_estimate', 'estimate_sent', 'estimate_approved',
            'in_progress', 'awaiting_parts', 'quality_check', 'ready_for_pickup'];

        $columns = [];
        foreach ($statuses as $st) {
            $q = VrcRepairOrder::with('vehicle')->where('business_id', $bid)->where('status', $st);
            if ($mine) {
                $q->whereIn('id', RoLine::where('business_id', $bid)
                    ->where('assigned_technician_id', $uid)->pluck('repair_order_id'));
            }
            $columns[] = [
                'status' => $st,
                'label'  => __('vrc::lang.ro_status_' . $st),
                'orders' => $q->orderByDesc('updated_at')->limit(50)->get()
                    ->map(fn ($ro) => $this->orderCard($ro))->values(),
            ];
        }

        return response()->json(['columns' => $columns]);
    }

    public function order(Request $request, int $id): JsonResponse
    {
        $bid = $this->bid($request);
        $ro = VrcRepairOrder::with(['vehicle', 'services', 'parts'])->where('business_id', $bid)->find($id);
        if (! $ro) {
            return response()->json(['message' => 'Not found'], 404);
        }
        $customer = \App\Contact::find($ro->erp_customer_id);

        return response()->json([
            'order' => $this->orderCard($ro) + [
                'customer'          => optional($customer)->name,
                'customer_phone'    => optional($customer)->mobile,
                'customer_concerns' => $ro->customer_concerns,
                'is_rework'         => (bool) $ro->is_rework,
                'allowed'           => $this->orders->machine()->allowedFrom($ro->status),
                'lines'             => $ro->services->map(fn ($s) => [
                    'id'           => $s->id,
                    'description'  => $s->description,
                    'status'       => $s->status,
                    'labor_hours'  => (float) $s->labor_hours,
                    'assigned_to'  => $s->assigned_technician_id,
                    'mine'         => (int) $s->assigned_technician_id === (int) $this->user($request)->id,
                    'stage_status' => $s->stage_status,
                ])->values(),
                'parts'             => $ro->parts->map(fn ($p) => [
                    'description' => $p->description, 'qty' => (float) $p->qty,
                ])->values(),
            ],
        ]);
    }

    public function transition(Request $request, int $id): JsonResponse
    {
        $u = $this->user($request);
        if (! $u->can('vrc.repair_order.manage')) {
            return response()->json(['message' => 'Not allowed.'], 403);
        }
        $data = $request->validate(['to' => 'required|string|max:40']);
        $ro = VrcRepairOrder::where('business_id', $this->bid($request))->find($id);
        if (! $ro) {
            return response()->json(['message' => 'Not found'], 404);
        }

        try {
            $this->orders->transition($ro, $data['to'], $u->id, $request->input('reason', 'staff app'));
            return response()->json(['ok' => true, 'status' => $ro->fresh()->status]);
        } catch (\Throwable $e) {
            return response()->json(['message' => $e->getMessage()], 422);
        }
    }

    public function lineStatus(Request $request, int $id, int $line): JsonResponse
    {
        $u = $this->user($request);
        if (! $u->can('vrc.repair_order.manage')) {
            return response()->json(['message' => 'Not allowed.'], 403);
        }
        $data = $request->validate(['status' => 'required|in:pending,in_progress,done,skipped']);

        $row = RoLine::where('business_id', $this->bid($request))->where('repair_order_id', $id)->find($line);
        if (! $row) {
            return response()->json(['message' => 'Not found'], 404);
        }
        $row->update(['status' => $data['status']]);

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

    public function laborStart(Request $request, int $id): JsonResponse
    {
        $u = $this->user($request);
        $data = $request->validate(['repair_order_service_id' => 'nullable|integer']);
        $ro = VrcRepairOrder::where('business_id', $this->bid($request))->find($id);
        if (! $ro) {
            return response()->json(['message' => 'Not found'], 404);
        }

        // Don't double-open a clock for the same line + tech.
        $open = VrcRepairOrderLaborLog::where('repair_order_id', $id)
            ->where('technician_id', $u->id)->whereNull('ended_at')
            ->when($data['repair_order_service_id'] ?? null, fn ($q, $v) => $q->where('repair_order_service_id', $v))
            ->first();
        if ($open) {
            return response()->json(['ok' => true, 'log_id' => $open->id, 'already_running' => true]);
        }

        $log = VrcRepairOrderLaborLog::create([
            'business_id'             => $ro->business_id,
            'repair_order_id'         => $ro->id,
            'repair_order_service_id' => $data['repair_order_service_id'] ?? null,
            'technician_id'           => $u->id,
            'started_at'              => now(),
        ]);

        return response()->json(['ok' => true, 'log_id' => $log->id]);
    }

    public function laborStop(Request $request, int $id): JsonResponse
    {
        $u = $this->user($request);
        $log = VrcRepairOrderLaborLog::where('repair_order_id', $id)
            ->where('technician_id', $u->id)->whereNull('ended_at')
            ->orderByDesc('id')->first();
        if (! $log) {
            return response()->json(['message' => 'No running timer.'], 422);
        }
        $log->ended_at = now();
        $log->duration_min = max(0, $log->started_at->diffInMinutes($log->ended_at));
        $log->save();

        return response()->json(['ok' => true, 'duration_min' => $log->duration_min]);
    }

    public function inspection(Request $request, int $id): JsonResponse
    {
        $insp = VrcInspection::with('results')->where('business_id', $this->bid($request))->find($id);
        if (! $insp) {
            return response()->json(['message' => 'Not found'], 404);
        }

        return response()->json([
            'inspection' => [
                'id'     => $insp->id,
                'type'   => $insp->type,
                'status' => $insp->status,
                'results' => $insp->results->map(fn ($r) => [
                    'id' => $r->id, 'label' => $r->label, 'result' => $r->result, 'note' => $r->note,
                ])->values(),
                'test_drive_done'   => (bool) $insp->test_drive_done,
                'test_drive_result' => $insp->test_drive_result,
            ],
        ]);
    }

    public function saveInspection(Request $request, int $id): JsonResponse
    {
        $u = $this->user($request);
        if (! $u->can('vrc.inspection.manage')) {
            return response()->json(['message' => 'Not allowed.'], 403);
        }
        $insp = VrcInspection::where('business_id', $this->bid($request))->find($id);
        if (! $insp) {
            return response()->json(['message' => 'Not found'], 404);
        }

        foreach ((array) $request->input('results', []) as $rid => $fields) {
            \Modules\Vrc\Entities\VrcInspectionResult::where('inspection_id', $insp->id)->where('id', $rid)
                ->update(['result' => $fields['result'] ?? null, 'note' => $fields['note'] ?? null]);
        }

        $td = $request->input('test_drive_result');
        $insp->update([
            'status'            => $request->boolean('complete') ? 'completed' : $insp->status,
            'test_drive_done'   => $request->boolean('test_drive_done'),
            'test_drive_result' => in_array($td, ['pass', 'fail'], true) ? $td : null,
            'test_drive_notes'  => $request->input('test_drive_notes'),
        ]);

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

    private function orderCard(VrcRepairOrder $ro): array
    {
        return [
            'id'           => $ro->id,
            'number'       => $ro->number ?: ('#' . $ro->id),
            'status'       => $ro->status,
            'status_label' => __('vrc::lang.ro_status_' . $ro->status),
            'priority'     => $ro->priority,
            'vehicle'      => optional($ro->vehicle)->label ?? optional($ro->vehicle)->plate_number,
            'promised_at'  => optional($ro->promised_at)->toIso8601String(),
            'is_rework'    => (bool) $ro->is_rework,
        ];
    }
}
