<?php

namespace App\Exports;

use App\Facades\Settings;
use App\Support\FeedDescription;
use App\Facades\Site;
use Illuminate\Database\Eloquent\Builder;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Mtc\MercuryDataModels\Vehicle;

class GoogleFeedExport implements FromQuery, WithHeadings, WithMapping
{
    public function __construct(protected $vehicles = null)
    {
    }

    public function query(): Builder
    {
        return Vehicle::query()
            ->with([
                'mediaUses.media',
                'dealership:id,name,address1,city,postcode,country,data',
                'make:id,name',
                'model:id,name',
                'bodyStyle:id,name',
                'defaultFinanceExample'
            ])
            ->exportable()
            ->where('price', '>', 0);
    }

    /**
     * Map each row of data to the required format
     *
     * @param Vehicle $row
     * @return array
     */
    public function map($row): array
    {
        return [
            'store_code' => $this->getStoreCode($row),
            'title' => $row->make?->name . ' ' . $row->model?->name . ' ' . $row->derivative,
            'id' => $row->id,
            'VIN' => $row->vin,
            'year' => $row->manufacture_year,
            'brand' => $row->make?->name,
            'model' => $row->model?->name,
            'trim' => $row->trim,
            'color' => $row->colour,
            'interior_color' => '',
            'mileage' => Settings::get('automotive-distance_measurement') === 'mi'
                ? ($row->odometer_mi ?? 0) . ' miles'
                : ($row->odometer_km ?? 0) . ' kilometres',
            'condition' => $row->is_new ? 'new' : 'used',
            'price' => $row->price . ' GBP',
            'dealership_name' => $row->dealership?->name,
            'dealership_address' => $row->dealership?->address1,
            'link' => Site::vehicleUrl($row),
            'image_link' =>  $row->mediaUses
                ->filter(fn ($mediaUse) => $mediaUse->primary)
                ->first()
                ?->getUrl('large'),
            'additional_image_link' => $row->mediaUses
                ->reject(fn ($mediaUse) => $mediaUse->primary)
                ->take(20)
                ->map(fn ($mediaUse) => $mediaUse->getUrl('large'))
                ->implode(","),
            'description' => strip_tags(FeedDescription::for($row)),
            'availability' => 'in_stock',
            'vehicle_option' => '',
            'vehicle_fulfillment' => 'in_store:' . $this->getStoreCode($row),
            'legal_disclaimer' => '',
            'google_product_category' => 'Vehicles & Parts > Vehicles > Motor Vehicles > Cars, Trucks & Vans',
            'link_template' => Site::vehicleUrl($row) . '?store={store_code}',
            'body_style' => $row->bodyStyle?->name,
            'installment(months:amount:downpayment:credit_type)' => $this->formatInstallment(
                months: $row->defaultFinanceExample?->number_of_payments,
                amount: $row->defaultFinanceExample?->monthly_price,
                downpayment: $row->defaultFinanceExample?->customer_deposit,
                finance: 'finance'
            ),
            'custom_label_0' => $row->model?->name,
            'custom_label_1' => $row->bodyStyle?->name,
        ];
    }

    private function formatInstallment(?int $months, ?float $amount, ?float $downpayment, string $finance)
    {
        $formattedMonths = $months ?? 0;
        $formattedAmount = round($amount ?? 0, 2) . ' ' . Settings::get('app-details-currency');
        $formattedDownpayment = round($downpayment ?? 0, 2) . ' ' . Settings::get('app-details-currency');

        return "{$formattedMonths}:{$formattedAmount}:{$formattedDownpayment}:{$finance}";
    }

    /**
     * Heading row
     *
     * @return string[]
     */
    public function headings(): array
    {
        return [
            'store_code',
            'title',
            'id',
            'VIN',
            'year',
            'brand',
            'model',
            'trim',
            'color',
            'interior_color',
            'mileage',
            'condition',
            'price',
            'dealership_name',
            'dealership_address',
            'link',
            'image_link',
            'additional_image_link',
            'description',
            'availability',
            'vehicle_option',
            'vehicle_fulfillment',
            'legal_disclaimer',
            'google_product_category',
            'link_template',
            'body_style',
            'installment(months:amount:downpayment:credit_type)',
            'custom_label_0',
            'custom_label_1',
        ];
    }

    public function getAddress($row)
    {
        return json_encode([
            'addr1' => $row->dealership?->address1,
            'city' => $row->dealership?->city,
            'region' => $row->dealership?->country == 'GB' ? 'UK' : null,
            'postal_code' => $row->dealership?->postcode,
            'country' => $row->dealership?->country,
        ]);
    }

    protected function getStoreCode(Vehicle $row)
    {
        return $row->dealership?->data['google-store-code']
            ?? Settings::get('sales-channels-google-store-code', null);
    }
}
