<?php

namespace App\Http\Resources;

use App\Facades\Settings;
use App\Facades\Site;
use App\IntegrationRepository;
use App\Services\RemoveBg;
use App\Traits\MakeAndModelList;
use App\VehicleType;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\DrivetrainType;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\SeoData;
use Mtc\MercuryDataModels\Services\FinanceServiceHelper;
use Mtc\MercuryDataModels\Traits\HasVehicleCustomAttributes;
use Mtc\MercuryDataModels\TransmissionType;

class VehicleViewResource extends JsonResource
{
    use ResourceMediaEntries;
    use HasVehicleCustomAttributes;
    use MakeAndModelList;

    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        $this->resource->load([
            'mediaUses.media',
            'features',
            'equipment',
            'make',
            'model',
            'specs',
            'financeExamples',
            'labels',
        ]);

        $vehicle = $this->resource->toArray();
        $vehicle['dealership_name'] = $this->resource->dealership?->name;
        $vehicle = array_merge($vehicle, $this->getMediaEntries());
        $vehicle['seo'] = $this->getSeoData();
        $vehicle['stats'] = $this->getStats();
        $vehicle['data'] = $this->resource->data ?? [];
        $vehicle['autotrader_data'] = $this->getAutoTraderData();
        $vehicle['alerts'] = $this->getAlerts();
        $vehicle['has_finance_provider'] = FinanceServiceHelper::hasEnabledProvider();
        $vehicle['finance_defaults'] = [
            'term' => Settings::get('finance-term'),
            'annual_mileage' => Settings::get('finance-annual_mileage'),
            'deposit_percentage' =>  Settings::get('finance-deposit_percentage'),
            'credit_rating' => Settings::get('finance-credit_rating'),
        ];

        if (!empty($this->resource->slug)) {
            $vehicle['site_url'] = Site::vehicleUrl($this->resource, true);
        }

        $vehicle['extra'] = $this->getExtraData($this->resource);

        return [
            'vehicle' => $vehicle,
            'types' => collect(VehicleType::cases())
                ->map(fn(VehicleType $type) => [
                    'name' => ucwords(strtolower($type->name)),
                    'id' => $type->value,
                ]),
            'makes' => $this->getMakeList(),
            'models' => $this->getModelList($this->resource->make_id),
            'fuel_types' => FuelType::all(),
            'drivetrains' => DrivetrainType::all(),
            'body_styles' => BodyStyleType::all(),
            'transmissions' => TransmissionType::all(),
            'sales_channels' => (new IntegrationRepository())->getAllForType('sales-channels', true)
                ->map(fn($channel, $id) => [
                    'id' => $id,
                    'name' => $channel['image']['alt'],
                    'active' => $channel['active'] ?? false,
                ])->values(),
            'monthly_cost_types' => config('automotive.monthly_cost_types', []),
            'settings' => [
                'distance_measurement' => Settings::get('automotive-distance_measurement'),
                'show_ai_button' => !empty(Settings::get('open-ai-api_key')),
                'show_remove_background_button' => RemoveBg::enabled(),
            ],
        ];
    }

    private function getSeoData(): array
    {
        $seoData = SeoData::query()->where('path', '/vehicles/' . $this->resource->slug)->first();
        if ($seoData) {
            return $seoData->only([
                'title',
                'description',
                'json_schema'
            ]);
        }

        return [
            'title' => '',
            'description' => '',
            'json_schema' => '',
        ];
    }

    private function getStats(): array
    {
        $views = $this->resource->views()
            ->where('date', '>=', Carbon::now()->subWeek()->format('Y-m-d'))
            ->orderBy('date')
            ->get();

        $conversions = $this->resource->conversions()
            ->where('date', '>=', Carbon::now()->subWeek()->format('Y-m-d'))
            ->orderBy('date')
            ->get()
            ->groupBy('type');

        return [
            'days_in_stock' => $this->resource->days_in_stock,
            'days_since_update' => $this->resource->days_since_update,
            'enquiries' => $this->resource->allEnquiries()->count(),
            'views_today' => $views
                    ->where('date', Carbon::now()->format('Y-m-d'))
                    ->pluck('hits')
                    ->first() ?? 0,
            'views_week' => $views
                    ->where('date', '>=', Carbon::now()->subWeek()->format('Y-m-d'))
                    ->sum('hits') ?? 0,
            'views_month' => $views
                    ->where('date', '>=', Carbon::now()->subMonth()->format('Y-m-d'))
                    ->sum('hits') ?? 0,
            'filter_views_today' => $views
                    ->where('date', Carbon::now()->format('Y-m-d'))
                    ->pluck('filter_views')
                    ->first() ?? 0,
            'filter_views_week' => $views
                    ->where('date', '>=', Carbon::now()->subWeek()->format('Y-m-d'))
                    ->sum('filter_views') ?? 0,
            'filter_views_month' => $views
                    ->where('date', '>=', Carbon::now()->subMonth()->format('Y-m-d'))
                    ->sum('filter_views') ?? 0,

            'graph' => [
                'labels' => $views->pluck('date')->unique()->map(fn($date) => Carbon::parse($date)->format('dS M')),
                'datasets' => [
                        [
                            'label' => 'Full page advert views',
                            'backgroundColor' => '#600000',
                            'data' => $views->pluck('hits'),
                            'tension' => 0.5
                        ],
                        [
                            'label' => 'Views in search results',
                            'backgroundColor' => '#000060',
                            'data' => $views->pluck('filter_views'),
                            'tension' => 0.5
                        ],
                    ],
            ],
            'conversions' => $conversions
                ->map(fn($data, $type) => [
                    'name' => __('vehicles.conversions.' . $type),
                    'today' => $data
                        ->where('date', Carbon::now()->format('Y-m-d'))
                        ->pluck('hits')
                        ->first() ?? 0,
                    'week' => $data
                        ->where('date', Carbon::now()->format('Y-m-d'))
                        ->sum('hits'),
                ])
                ->values()
        ];
    }

    private function getAutoTraderData(): ?array
    {
        return $this->resource->autoTraderData
            ?->getDisplayAttributes()
            ->map(fn($attribute, $key) => [
                'id' => $key,
                'name' => __("vehicles.auto-trader.$key"),
                'value' => $attribute . ($key === 'price_position' ? '%' : ''),
            ])
            ->values()
            ->toArray();
    }

    private function getAlerts(): array
    {
        $alerts = [];
        if ($this->hasExternalSync()) {
            $alerts[] = [
                'type' => 'warning',
                'errors' => [ __('vehicles.external_sync_warning') ],
            ];
        }


        return $alerts;
    }

    private function hasExternalSync(): bool
    {
        return !empty($this->resource->uuid)
            && (new IntegrationRepository())->getEnabledForType('stock')->has($this->resource->stock_provider);
    }
}
