<?php

namespace Modules\Bms\Http\Controllers\Api;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Modules\Bms\Entities\BmsOfficeVisit;
use Modules\Bms\Entities\BmsVenue;
use Modules\Bms\Entities\BmsWizardSession;

/**
 * Office-visit scheduling for the client funnel. If the client's selected
 * halls span multiple locations the plan proposes one visit per location
 * (same-location halls share a visit) — `plan()` returns that grouping.
 */
class VisitController extends ApiController
{
    /** Proposed visits: one per distinct location across the lead's selected halls. */
    public function plan(string $token)
    {
        $session = BmsWizardSession::where('token', $token)->first();
        if (! $session || ! $session->lead_id) {
            return $this->fail('Capture contact details and select halls first', 422);
        }

        $rows = DB::table('bms_lead_halls')
            ->join('bms_halls', 'bms_halls.id', '=', 'bms_lead_halls.hall_id')
            ->leftJoin('business_locations', 'business_locations.id', '=', 'bms_halls.location_id')
            ->where('bms_lead_halls.lead_id', $session->lead_id)
            ->get(['bms_halls.location_id', 'business_locations.name as location_name', 'bms_halls.name as hall_name']);

        $plan = $rows->groupBy('location_id')->map(fn ($g, $locId) => [
            'location_id'   => $locId ? (int) $locId : null,
            'location_name' => optional($g->first())->location_name,
            'halls'         => $g->pluck('hall_name')->values(),
            'hours'         => $this->locationHours((int) $session->business_id, $locId ? (int) $locId : null),
        ])->values();

        return $this->ok(['visits' => $plan]);
    }

    /**
     * Effective working hours for a location — derived from a venue at that
     * location (its custom hours or the business default). Drives the client's
     * date/time picker so visits are only offered on open days/times (2.6).
     */
    protected function locationHours(int $businessId, ?int $locationId): array
    {
        $venue = BmsVenue::where('business_id', $businessId)
            ->when($locationId, fn ($q) => $q->where('location_id', $locationId))
            ->where('is_active', true)
            ->first();

        $hours = $venue
            ? $venue->effectiveHours()
            : ['days' => [0, 1, 2, 3, 4, 5, 6], 'open' => '10:00', 'close' => '22:00'];

        return [
            'days'  => array_values(array_map('intval', (array) ($hours['days'] ?? [0, 1, 2, 3, 4, 5, 6]))),
            'open'  => $hours['open'] ?? '10:00',
            'close' => $hours['close'] ?? '22:00',
        ];
    }

    /** Book one or more office visits. */
    public function book(Request $request, string $token)
    {
        $session = BmsWizardSession::where('token', $token)->first();
        if (! $session || ! $session->lead_id) {
            return $this->fail('Capture contact details first', 422);
        }

        $data = $request->validate([
            'visits'               => 'required|array|min:1',
            'visits.*.location_id' => 'nullable|integer',
            'visits.*.visit_date'  => 'required|date|after_or_equal:today',
            'visits.*.visit_time'  => 'nullable|date_format:H:i',
            'visits.*.notes'       => 'nullable|string|max:255',
        ]);

        $created = [];
        foreach ($data['visits'] as $v) {
            $created[] = BmsOfficeVisit::create([
                'business_id'       => $session->business_id,
                'lead_id'           => $session->lead_id,
                'contact_id'        => $session->contact_id,
                'location_id'       => $v['location_id'] ?? null,
                'wizard_session_id' => $session->id,
                'visit_date'        => $v['visit_date'],
                'visit_time'        => $v['visit_time'] ?? null,
                'notes'             => $v['notes'] ?? null,
                'status'            => 'requested',
            ]);
        }

        // Notify the client through the configured channels (best-effort).
        $contact = $session->contact_id ? \App\Contact::find($session->contact_id) : null;
        if ($contact) {
            // Prefer the captured WhatsApp number (may differ from the phone).
            $lead = $session->lead_id ? \Modules\Bms\Entities\BmsLead::find($session->lead_id) : null;
            $wa = $lead?->whatsapp ?: $session->contact_whatsapp ?: $contact->mobile;
            $to = array_values(array_filter([$wa, $contact->email]));
            if (! empty($to)) {
                try {
                    app(\Modules\Bms\Services\Notifications\NotificationRouter::class)->notify(
                        (int) $session->business_id, 'visit_booked', $to,
                        'تم حجز زيارتك — Askar Group',
                        'تم حجز زيارتك للقاعة. سيتواصل معك فريق المبيعات لتأكيد الموعد. / Your venue visit is booked; our team will confirm shortly.',
                        [], 'visit_booked:' . $session->id
                    );
                } catch (\Throwable $e) {
                    \Log::warning('[BMS] visit notification failed: ' . $e->getMessage());
                }
            }
        }

        return $this->ok(['visits' => $created, 'count' => count($created)]);
    }
}
