<?php

namespace App\Exports;

use App\Facades\Settings;
use App\SalesChannelType;
use App\Traits\UsesSalesChannelRules;
use App\VehicleType;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Mtc\ContentManager\Models\MediaUse;
use Mtc\MercuryDataModels\Vehicle;

class CarzoneExport implements FromCollection, WithHeadings
{
    use UsesSalesChannelRules;

    /**
     * @return \Illuminate\Support\Collection
     */
    public function collection()
    {
        return Vehicle::query()
            ->with([
                'mediaUses.media',
                'dealership',
                'make',
                'model',
                'transmission',
                'fuelType',
                'bodyStyle',
                'features',
                'specs',
                'equipment',
            ])
            ->when(Settings::get('automotive-sales-channels-carzone-remove-sold'), function ($query) {
                $query->where('is_sold', false);
            })
            ->when(Settings::get('automotive-sales-channels-carzone-remove-reserved'), function ($query) {
                $query->where('is_reserved', false);
            })
            ->when(
                $this->hasSalesChannelRules(SalesChannelType::CARZONE),
                fn($query) => $this->applyQueryConditionsForChannel($query, SalesChannelType::CARZONE)
            )
            ->exportable()
            ->get()
            ->map(function (Vehicle $vehicle) {
                return [
                    'vehicleid' => $this->getValue($vehicle->uuid),
                    'registration' => str_replace(' ', '', $this->getValue($vehicle->registration_number)),
                    'year' => $this->getValue($vehicle->manufacture_year),
                    'make' => $this->getValue($vehicle->make?->name),
                    'model' => $this->getValue($vehicle->model?->name),
                    'variant' => $this->getValue($vehicle->derivative),
                    'enginesize' => $this->getValue($vehicle->engine_size_cc),
                    'fueltype' => $this->getValue($vehicle->fuelType?->name),
                    'colour' => $this->getValue($vehicle->colour),
                    'manufacturercolour' => $this->getValue($vehicle->colour),
                    'doors' => $this->getValue($vehicle->door_count),
                    'mileage' => $this->getValue($vehicle->odometer_mi, true),
                    'mileageunit' => 'm',
                    'owners' => $vehicle->previous_owner_count,
                    'extras' => $this->getExtras($vehicle),
                    'price' => $this->getValue(round($vehicle->price), true),
                    'picturerefs' => $vehicle->mediaUses
                        ->filter(fn($mediaUse) => $mediaUse->media)
                        ->map(fn(MediaUse $mediaUse) => $mediaUse->media->getOriginalUrlAttribute(true))
                        ->implode(','),
                    'bodytype' => $vehicle->bodyStyle?->name,
                    'transmission' => $this->getValue($vehicle->transmission?->name),
                    'description' => $this->getValue($vehicle->description),
                    'isaproved' => $vehicle->is_published ? '1' : '0',
                    'category' => $vehicle->type == VehicleType::LCV ? 'COMM' : 'CARS',
                    'feedid' => $this->getValue($vehicle->dealership?->data['carzone-dealer-id']),
                    'nct' => '',
                    'priceperweek' => 'POA',
                    'video' => $vehicle->main_video_url,
                    'customwalkaround' => '',
                    'exterior360' => $vehicle->exterior_video_url,
                    'interior360' => $vehicle->interior_video_url,
                    'isfeatured' => $vehicle->featured ? 'Y' : 'N',
                    'seats' => $vehicle->seats,
                ];
            });
    }

    /**
     * Heading row
     *
     * @return string[]
     */
    public function headings(): array
    {
        return [
            'StockNo',
            'Reg',
            'Year',
            'Make',
            'Model',
            'Variant',
            'Engine',
            'Fuel',
            'Colour',
            'Manufacturer colour',
            'Doors',
            'Mileage',
            'Mileage_Unit',
            'Owners',
            'Extras',
            'Price',
            'AllImages',
            'BodyType',
            'Gearbox',
            'Summary',
            'IsApproved',
            'Category',
            'DearlerID',
            'NCT',
            'PricePerWeek',
            'Video',
            'Custom Walkaround',
            'Exterior360Link',
            'Interior360Link',
            'IsFeatured',
            'Seats',
        ];
    }

    private function getValue($value = false, $forceZeroString = false)
    {
        if (!empty($value)) {
            return $value;
        }

        // item equates to empty
        if ($forceZeroString) {
            return '0';
        }

        return false;
    }

    private function getExtras(Vehicle $vehicle)
    {
        $specs = $vehicle->specs->pluck('description')
            ->filter(function ($value) {
                return !empty(trim($value));
            })
            ->map(function ($value) {
                return trim($value);
            });

        if ($specs->count()) {
            return $specs->implode(',');
        }

        $features = $vehicle->features->pluck('name')
            ->filter(function ($value) {
                return !empty(trim($value));
            })
            ->map(function ($value) {
                return trim($value);
            });

        if ($features->count()) {
            return $features->implode(',');
        }

        $equipment = $vehicle->equipment->pluck('description')
            ->filter(function ($value) {
                return !empty(trim($value));
            })
            ->map(function ($value) {
                return trim($value);
            });

        if ($equipment->count()) {
            return $equipment->implode(',');
        }

        return '';
    }
}
