<?php

namespace App\Exports;

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

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

    public function collection()
    {
        return $this->vehicles ?: collect();
    }

    public function query(): Builder
    {
        return Vehicle::query()
            ->with([
                'mediaUses.media',
                'dealership',
                'make',
                'model',
                'transmission',
                'fuelType',
                'bodyStyle',
                'specs',
            ])
            ->exportable();
    }

    /**
     * Map each row of data to the required format
     *
     * @param Vehicle $row
     * @return array
     */
    public function map($row): array
    {
        $mappedData = [
            'vehicle_id' => $row->id,
            'title' => $row->make?->name . ' ' . $row->model?->name,
            'price' => $row->price,
            'sale_price' => null,
            'body_style' => $row->bodyStyle?->name,
            'address' => $this->getAddress($row),
            'street_address' => $row->dealership?->address1,
            'description' => Str::limit(strip_tags(FeedDescription::for($row)), 180),
            'exterior_color' => $row->colour,
            'fb_page_id' => $row->uuid,
            'latitude' => $row->dealership?->lat ?? null,
            'longitude' => $row->dealership?->lng ?? null,
            'make' => $row->make?->name,
            'model' => $row->model?->name,
            'mileage.unit' => Settings::get('automotive-distance_measurement') === 'mi'
                ? 'MI'
                : 'KM',
            'mileage.value' => Settings::get('automotive-distance_measurement') === 'mi'
                ? $row->odometer_mi
                : $row->odometer_km,
            'state_of_vehicle' => $row->is_new ? 'New' : 'Used',
            'url' => Site::vehicleUrl($row),
            'year' => $row->manufacture_year,
            'vin' => $row->vin,
            'availability' => 'Available',
            'chrome_id' => null,
            'condition' => null,
            'custom_label_0' => null,
            'custom_label_1' => null,
            'custom_label_2' => null,
            'date_first_on_lot' => $row->created_at,
            'days_on_lot' => Carbon::now()->diffInDays($row->created_at, true),
            'dealer_communication_channel' => null,
            'dealer_id' => $row->dealership_id,
            'dealer_name' => $row->dealership?->name,
            'dealer_phone' => $row->dealership?->contact_num,
            'dealer_privacy_policy_url' => null,
            'drivetrain' => null,
            'fuel_type' => $row->fuelType?->name,
            'address.postal_code' => $row->dealership?->postcode,
            'stock_number' => $row->uuid,
            'transmission' => $row->transmission?->name,
            'trim' => $row->trim,
            'tag' => null,
            'deep_link' => Site::vehicleUrl($row),
            'monthly_price' => $row->monthly_price
        ];

        $mainImage = $row->mediaUses
            ->filter(fn ($mediaUse) => $mediaUse->primary)
            ->first()
            ?->getUrl('large');

        $otherImages = $row->mediaUses
            ->reject(fn ($mediaUse) => $mediaUse->primary)
            ->take(20)
            ->map(fn ($mediaUse) => $mediaUse->getUrl('large'))
            ->values()
            ->toArray();

        $mappedData["image[0].url"] = $mainImage ?? null;
        for ($i = 1; $i < 20; $i++) {
            $mappedData["image[$i].url"] = $otherImages[$i - 1] ?? null;
        }

        return $mappedData;
    }

    /**
     * Heading row
     *
     * @return string[]
     */
    public function headings(): array
    {
        $headings =  [
            'vehicle_id',
            'title',
            'price',
            'sale_price',
            'body_style',
            'address',
            'street_address',
            'description',
            'exterior_color',
            'fb_page_id',
            'latitude',
            'longitude',
            'make',
            'model',
            'mileage.unit',
            'mileage.value',
            'state_of_vehicle',
            'url',
            'year',
            'vin',
            'availability',
            'chrome_id',
            'condition',
            'custom_label_0',
            'custom_label_1',
            'custom_label_2',
            'date_first_on_lot',
            'days_on_lot',
            'dealer_communication_channel',
            'dealer_id',
            'dealer_name',
            'dealer_phone',
            'dealer_privacy_policy_url',
            'drivetrain',
            'fuel_type',
            'address.postal_code',
            'stock_number',
            'transmission',
            'trim',
            'tag',
            'deep_link',
            'monthly_price'
        ];

        for ($i = 0; $i < 20; $i++) {
            $headings[] = "image[" . $i . "].url";
        }

        return $headings;
    }

    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,
        ]);
    }
}
