<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\View\View;
use Illuminate\Support\Str;
use Mtc\MercuryDataModels\Booking;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\Invoice;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\VehicleReservations\Reservation;
use Mtc\VehicleReservations\VehicleMoveRequest;

class DocsController extends Controller
{
    /**
     * API docs page
     * @return View
     */
    public function swagger()
    {
        return view('docs.swagger');
    }

    /**
     * Email preview
     *
     * @return View
     */
    public function mail()
    {
        return view('docs.mail', [
            'mailables' => collect(config('mail.preview_mailables'))
                ->map(fn ($class, $name) => str_replace('-', ' ', Str::title($name)))
        ]);
    }

    /**
     * Preview single email
     *
     * @param string $mailable
     * @return mixed
     */
    public function viewMail(string $mailable)
    {
        $class = config("mail.preview_mailables.$mailable");

        return match ($mailable) {
            'invoice-notification', 'overdue-invoice-notification' => $this->invoiceMail($class),
            'new-service-booking', 'new-service-booking-confirmation' => $this->bookingMail($class),
            'enquiry', 'enquiry-customer-copy' => $this->enquiryMail($class),
            'free-hold-customer', 'free-hold-team', 'free-hold-expiry-reminder' => $this->reservationMail($class),
            'move-request-team' => $this->moveRequestMail($class),
        };
    }

    /**
     * Create mail with dummy data
     *
     * @param $mail_object
     * @return mixed
     */
    private function invoiceMail($mail_object)
    {
        $invoice = Invoice::factory()->make();
        return new $mail_object($invoice);
    }

    private function bookingMail($mail_object)
    {
        if (session()->has('current_tenant')) {
            tenancy()->initialize(session('current_tenant'));
        }
        $booking = Booking::query()->inRandomOrder()->first();
        if (!$booking) {
            $booking = Booking::factory()->make();
        }
        return new $mail_object($booking);
    }

    private function enquiryMail($mail_object)
    {
        if (session()->has('current_tenant')) {
            tenancy()->initialize(session('current_tenant'));
            $enquiry = Enquiry::query()->first();
        }
        if (empty($enquiry)) {
            $enquiry = Enquiry::factory()->make();
        }
        return new $mail_object($enquiry);
    }

    private function reservationMail($mail_object)
    {
        $reservation = null;
        if (session()->has('current_tenant')) {
            tenancy()->initialize(session('current_tenant'));
            $reservation = Reservation::query()->with(['vehicle.make', 'vehicle.model'])->latest()->first();
        }
        if (empty($reservation)) {
            $reservation = Reservation::factory()->make();
        }
        $reservation->setRelation('vehicle', $this->previewVehicle($reservation));
        if (empty($reservation->expires_at)) {
            $reservation->expires_at = now()->addDays(3);
        }
        return new $mail_object($reservation);
    }

    private function moveRequestMail($mail_object)
    {
        $moveRequest = null;
        if (session()->has('current_tenant')) {
            tenancy()->initialize(session('current_tenant'));
            $moveRequest = VehicleMoveRequest::query()
                ->with(['vehicle.make', 'vehicle.model', 'fromDealership', 'toDealership'])
                ->latest()
                ->first();
        }
        if (empty($moveRequest)) {
            $moveRequest = VehicleMoveRequest::factory()->make();
        }
        $moveRequest->setRelation('vehicle', $this->previewVehicle($moveRequest));
        if (!$moveRequest->relationLoaded('fromDealership') || $moveRequest->getRelation('fromDealership') === null) {
            $moveRequest->setRelation('fromDealership', $this->previewDealership('Bristol Branch'));
        }
        if (!$moveRequest->relationLoaded('toDealership') || $moveRequest->getRelation('toDealership') === null) {
            $moveRequest->setRelation('toDealership', $this->previewDealership('Edinburgh Branch'));
        }
        return new $mail_object($moveRequest);
    }

    /**
     * Build a display-ready vehicle for email previews, backfilling any empty
     * fields (and the make/model relations) with sample values so every template
     * row renders regardless of the underlying record.
     *
     * @param mixed $payable Reservation or VehicleMoveRequest carrying the vehicle relation
     */
    private function previewVehicle($payable): Vehicle
    {
        $vehicle = $payable->relationLoaded('vehicle') ? $payable->getRelation('vehicle') : null;
        $vehicle = $vehicle ?: Vehicle::factory()->make();

        $vehicle->vrm_condensed = $vehicle->vrm_condensed ?: 'AB12CDE';
        $vehicle->derivative = $vehicle->derivative ?: 'Match SE 1.5 TSI 150';
        $vehicle->uuid = $vehicle->uuid ?: '00000000-0000-4000-8000-000000000000';
        $vehicle->slug = $vehicle->slug ?: 'sample-vehicle';

        if (!$vehicle->relationLoaded('make') || $vehicle->getRelation('make') === null) {
            $make = new VehicleMake();
            $make->name = 'Volkswagen';
            $make->slug = 'volkswagen';
            $vehicle->setRelation('make', $make);
        }
        if (!$vehicle->relationLoaded('model') || $vehicle->getRelation('model') === null) {
            $vehicleModel = new VehicleModel();
            $vehicleModel->name = 'Golf';
            $vehicleModel->slug = 'golf';
            $vehicle->setRelation('model', $vehicleModel);
        }

        return $vehicle;
    }

    private function previewDealership(string $name): Dealership
    {
        $dealership = new Dealership();
        $dealership->name = $name;
        return $dealership;
    }
}
