<?php

namespace App\Exports;

use App\Facades\Settings;
use App\Support\FeedDescription;
use App\Facades\Site;
use App\SalesChannelType;
use App\Traits\UsesSalesChannelRules;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Mtc\MercuryDataModels\Country;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;

class ChannelFeedExport implements FromQuery, WithHeadings, WithMapping, WithChunkReading
{
    use UsesSalesChannelRules;

    protected $countries;

    public function __construct()
    {
        $this->countries = Country::query()
            ->whereIn('code', Dealership::query()->pluck('country'))
            ->pluck('name', 'code');
    }

    public function query(): Builder
    {
        return Vehicle::query()
            ->with([
                'mediaUses.media',
                'dealership',
                'make',
                'model',
                'transmission',
                'fuelType',
                'bodyStyle',
                'specs',
                'attributeValues',
            ])
            ->exportable()
            ->when(
                $this->hasSalesChannelRules(SalesChannelType::CHANNEL_FEED),
                fn ($query) => $this->applyQueryConditionsForChannel($query, SalesChannelType::CHANNEL_FEED)
            );
    }

    /**
     * Map each row of data to the required format
     *
     * @param Vehicle $row
     * @return array
     */
    public function map($row): array
    {
        return [
            'vehicle_id' => $row->uuid,
            'vehicle_registration_id' => $row->registration_number,
            'title' => $row->title,
            'description' => Str::limit(strip_tags(FeedDescription::for($row)), 180),
            'url' => Site::vehicleUrl($row),
            'make' => $row->make?->name,
            'main_image' => $row->mediaUses
                ->filter(fn ($mediaUse) => $mediaUse->primary)
                ->first()
                ?->getUrl('large'),
            'additional_images' => $row->mediaUses
                ->reject(fn ($mediaUse) => $mediaUse->primary)
                ->map(fn ($mediaUse) => $mediaUse->getUrl('large'))
                ->implode(','),
            'model' => $row->model?->name,
            'model_year' => $row->manufacture_year,
            'mileage_value' => Settings::get('automotive-distance_measurement') === 'mi'
                ? $row->odometer_mi
                : $row->odometer_km,
            'mileage_unit' => Settings::get('automotive-distance_measurement') === 'mi'
                ? 'mi'
                : 'km',
            'vin' => $row->vin,
            'body_style' => $row->bodyStyle?->name,
            'fuel_type' => $row->fuelType?->name,
            'transmission' => $row->transmission?->name,
            'price' => $row->price,
            'colour' => $row->colour,
            'address_country' => $this->countries[$row->dealership?->country] ?? null,
            'doors_count' => $row->door_count,
            'engine_size' => $row->engine_size_cc,
            'previous_owner_count' => $row->previous_owner_count,
            'options' => $row->specs
                ->pluck('description')
                ->implode(','),
            'sale_price' => $row->price,
            'availability' => 'Available',
            'date_first_on_lot' => $row->first_registration_date,
            'state_of_vehicle' => $row->is_new ? 'New' : 'Used',
            'days_in_stock' => $row->days_in_stock,
            'derivative' => $row->derivative,
            'dealer_id' => $row->dealership?->data['channable-dealer-id'] ?? $row->dealership_id,
            'location' => $row->dealership?->title,
            'address1' => $row->dealership?->address1,
            'address2' => $row->dealership?->address2,
            'city' => $row->dealership?->city,
            'country' => $row->dealership?->country,
            'postcode' => $row->dealership?->postcode,
            'telephone_number' => $row->dealership?->contact_no,
            'email_address' => $row->dealership?->email,
            'coordinates' => $row->dealership?->coordinates,
            'attributes' => $row->getAllCustom(),
        ];
    }

    /**
     * Heading row
     *
     * @return string[]
     */
    public function headings(): array
    {
        return [
            'vehicle_id',
            'vehicle_registration_id',
            'title',
            'description',
            'url',
            'make',
            'main_image',
            'additional_images',
            'model',
            'model_year',
            'mileage_value',
            'mileage_unit',
            'vin',
            'body_style',
            'fuel_type',
            'transmission',
            'price',
            'colour',
            'address_country',
            'doors_count',
            'engine_size',
            'previous_owner_count',
            'options',
            'sale_price',
            'availability',
            'date_first_on_lot',
            'state_of_vehicle',
            'days_in_stock',
            'derivative',
            'dealer_id',
            'location',
            'address1',
            'address2',
            'city',
            'country',
            'postcode',
            'telephone_number',
            'email_address',
            'coordinates',
            'attributes'
        ];
    }

    /**
     * Define chunk size for better performance.
     *
     * @return int
     */
    public function chunkSize(): int
    {
        return 500;
    }
}
