<?php

namespace Modules\VrcPortalApi\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Vrc\Entities\VrcEstimate;
use Modules\Vrc\Entities\VrcPortalOwner;
use Modules\Vrc\Entities\VrcRepairOrder;
use Modules\Vrc\Entities\VrcVehicle;

/**
 * VRC owner PWA data endpoints. Everything is scoped to the authenticated
 * owner's business + ERP customer id, so an owner only ever sees their own
 * vehicles, repair orders, estimates and invoices.
 */
class OwnerController extends Controller
{
    private function owner(Request $request): VrcPortalOwner
    {
        return $request->attributes->get('vrc_owner');
    }

    /** PUBLIC: brand/config for the login screen. */
    public function brand(): JsonResponse
    {
        $biz = \App\Business::orderBy('id')->first();
        return response()->json([
            'name'       => optional($biz)->name ?: config('app.name', 'Service Center'),
            'accent_hex' => '#f97316',
            'app'        => 'VRC Owner',
        ]);
    }

    public function me(Request $request): JsonResponse
    {
        $o = $this->owner($request);
        return response()->json([
            'id' => $o->id, 'name' => $o->name, 'phone' => $o->phone, 'email' => $o->email,
        ]);
    }

    public function home(Request $request): JsonResponse
    {
        $o = $this->owner($request);

        $vehicles = VrcVehicle::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->get();

        $active = VrcRepairOrder::with('vehicle')
            ->where('business_id', $o->business_id)->where('erp_customer_id', $o->erp_customer_id)
            ->whereNotIn('status', ['completed', 'cancelled', 'invoiced'])
            ->orderByDesc('id')->limit(10)->get();

        $pendingEstimates = VrcEstimate::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->where('status', 'sent')->count();

        return response()->json([
            'greeting_name'    => $o->name,
            'vehicle_count'    => $vehicles->count(),
            'active_orders'    => $active->map(fn ($ro) => $this->orderCard($ro))->values(),
            'pending_estimates' => $pendingEstimates,
            'vehicles'         => $vehicles->map(fn ($v) => $this->vehicleCard($v))->values(),
        ]);
    }

    public function vehicles(Request $request): JsonResponse
    {
        $o = $this->owner($request);
        $rows = VrcVehicle::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->orderBy('id')->get();

        return response()->json(['vehicles' => $rows->map(fn ($v) => $this->vehicleCard($v))->values()]);
    }

    public function vehicle(Request $request, int $id): JsonResponse
    {
        $o = $this->owner($request);
        $v = VrcVehicle::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->find($id);
        if (! $v) {
            return response()->json(['message' => 'Not found'], 404);
        }

        $orders = VrcRepairOrder::where('business_id', $o->business_id)
            ->where('vehicle_id', $v->id)->orderByDesc('id')->limit(50)->get();

        return response()->json([
            'vehicle' => $this->vehicleCard($v) + [
                'vin'         => $v->vin,
                'odometer'    => $v->odometer,
                'color'       => $v->color,
                'fuel_type'   => $v->fuel_type ?? null,
            ],
            'history' => $orders->map(fn ($ro) => $this->orderCard($ro))->values(),
        ]);
    }

    public function orders(Request $request): JsonResponse
    {
        $o = $this->owner($request);
        $rows = VrcRepairOrder::with('vehicle')->where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->orderByDesc('id')->limit(50)->get();

        return response()->json(['orders' => $rows->map(fn ($ro) => $this->orderCard($ro))->values()]);
    }

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

        return response()->json([
            'order' => $this->orderCard($ro) + [
                'customer_concerns' => $ro->customer_concerns,
                'promised_at'       => optional($ro->promised_at)->toIso8601String(),
                'subtotal'          => (float) $ro->subtotal,
                'tax_total'         => (float) $ro->tax_total,
                'grand_total'       => (float) $ro->grand_total,
                'currency'          => $ro->currency,
                'is_rework'         => (bool) $ro->is_rework,
                'services'          => $ro->services->map(fn ($s) => [
                    'description' => $s->description,
                    'status'      => $s->status,
                    'qty'         => (float) $s->qty,
                    'line_total'  => (float) $s->line_total,
                ])->values(),
                'timeline'          => $ro->statusHistory->map(fn ($h) => [
                    'status'  => $h->to_status ?? $h->status ?? null,
                    'label'   => __('vrc::lang.ro_status_' . ($h->to_status ?? $h->status ?? 'draft')),
                    'at'      => optional($h->created_at)->toIso8601String(),
                ])->values(),
            ],
        ]);
    }

    public function estimates(Request $request): JsonResponse
    {
        $o = $this->owner($request);
        $rows = VrcEstimate::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)
            ->whereIn('status', ['sent', 'approved', 'declined', 'expired', 'converted'])
            ->orderByDesc('id')->limit(50)->get();

        return response()->json(['estimates' => $rows->map(fn ($e) => $this->estimateCard($e))->values()]);
    }

    public function approveEstimate(Request $request, int $id): JsonResponse
    {
        return $this->decide($request, $id, 'approved');
    }

    public function declineEstimate(Request $request, int $id): JsonResponse
    {
        return $this->decide($request, $id, 'declined');
    }

    private function decide(Request $request, int $id, string $decision): JsonResponse
    {
        $o = $this->owner($request);
        $est = VrcEstimate::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)->find($id);
        if (! $est) {
            return response()->json(['message' => 'Not found'], 404);
        }
        if ($est->status !== 'sent') {
            return response()->json(['message' => 'This estimate can no longer be changed.'], 422);
        }
        if ($est->valid_until && \Carbon\Carbon::parse($est->valid_until)->endOfDay()->isPast()) {
            return response()->json(['message' => 'This estimate has expired.'], 422);
        }

        $est->update([
            'status'          => $decision,
            'decided_at'      => now(),
            'decision_method' => 'portal_app',
        ]);

        // Best-effort: advance the linked repair order when approved.
        if ($decision === 'approved' && $est->repair_order_id) {
            try {
                $ro = VrcRepairOrder::find($est->repair_order_id);
                $svc = app(\Modules\Vrc\Services\RepairOrder\RepairOrderService::class);
                if ($ro && $svc->machine()->canTransition($ro->status, 'estimate_approved')) {
                    $svc->transition($ro, 'estimate_approved', null, 'owner app');
                }
            } catch (\Throwable $e) {
                // never fail the decision on a transition guard
            }
        }

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

    public function invoices(Request $request): JsonResponse
    {
        $o = $this->owner($request);
        $invoiceIds = VrcRepairOrder::where('business_id', $o->business_id)
            ->where('erp_customer_id', $o->erp_customer_id)
            ->whereNotNull('erp_invoice_id')->pluck('erp_invoice_id');

        $rows = \App\Transaction::whereIn('id', $invoiceIds)->orderByDesc('id')->limit(50)->get();

        return response()->json([
            'invoices' => $rows->map(function ($t) {
                $paid = (float) \App\TransactionPayment::where('transaction_id', $t->id)
                    ->where('is_return', 0)->sum('amount');
                return [
                    'id'             => $t->id,
                    'ref_no'         => $t->invoice_no ?? ('INV-' . $t->id),
                    'date'           => optional($t->transaction_date)->toDateString(),
                    'total'          => (float) $t->final_total,
                    'paid'           => $paid,
                    'due'            => round((float) $t->final_total - $paid, 2),
                    'payment_status' => $t->payment_status,
                ];
            })->values(),
        ]);
    }

    /* ── shaping helpers ─────────────────────────────────────────────── */

    private function vehicleCard(VrcVehicle $v): array
    {
        return [
            'id'    => $v->id,
            'label' => $v->label ?? trim(($v->year ? $v->year . ' ' : '') . ($v->plate_number ?? '')),
            'plate' => $v->plate_number,
            'year'  => $v->year,
            'odometer' => $v->odometer,
        ];
    }

    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),
            'vehicle'      => optional($ro->vehicle)->label ?? optional($ro->vehicle)->plate_number,
            'grand_total'  => (float) $ro->grand_total,
            'updated_at'   => optional($ro->updated_at)->toIso8601String(),
            'tracking_token' => $ro->tracking_token,
        ];
    }

    private function estimateCard(VrcEstimate $e): array
    {
        return [
            'id'          => $e->id,
            'number'      => $e->number ?: ('EST-' . $e->id),
            'status'      => $e->status,
            'grand_total' => (float) $e->grand_total,
            'currency'    => $e->currency,
            'valid_until' => $e->valid_until ? \Carbon\Carbon::parse($e->valid_until)->toDateString() : null,
            'can_decide'  => $e->status === 'sent',
        ];
    }
}
