<?php

namespace App\Http\Resources;

use App\Facades\Feature;
use App\Facades\Settings;
use App\TierHelper;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Mtc\ContentManager\Contracts\MediaUse;
use Mtc\ContentManager\Models\MediaSize;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\Menu;

trait FranchiseData
{
    protected function getFranchiseList(): array
    {
        if (!$this->tenantIsAllowedFranchises()) {
            return [];
        }

        return Franchise::query()
            ->with([
                'primaryMediaUse.media',
                'mediaUses.media',
                'menus',
                'make',
                'dealerships',
            ])
            ->get()
            ->map(function ($franchise) {

                $franchiseData = [
                    'id' => $franchise->id,
                    'name' => $franchise->name,
                    'slug' => $franchise->slug,
                    'make_id' => $franchise->make?->id,
                    'make_slug' => $franchise->make?->slug,
                    'menus' => $franchise->menus->map(fn(Menu $menu) => new MenuResource($menu)),
                    'primary_colour' => $franchise->primary_colour,
                    'secondary_colour' => $franchise->secondary_colour,
                    'dealerships' => $franchise->dealerships?->mapWithKeys(fn ($dealership) => [
                        $dealership->slug => [
                            'name' => $dealership->name,
                            'contact_no' => $dealership->contact_no,
                            'email' => $dealership->email,
                        ]
                    ])->toArray(),
                ];

                // find dealerships mapped to this franchise via the mapping relationship
                $dealerships = Dealership::query()->whereHas(
                    'franchises',
                    fn ($query) => $query->where('franchise_id', $franchise->id)
                )
                ->when(
                    Settings::get('dealerships-sort-order', 'name') === 'order',
                    fn($query) => $query->orderBy('order'),
                    fn($query) => $query->orderBy('name')
                )
                ->get()
                ->mapWithKeys(fn ($dealership) => [
                    $dealership->slug => [
                        'name' => $dealership->name,
                        'contact_no' => $dealership->contact_no,
                        'email' => $dealership->email,
                    ]
                ])->toArray();

                $franchiseData['dealerships'] = array_values(array_merge($franchiseData['dealerships'], $dealerships));

                if ($franchise->primaryMediaUse) {
                    $franchiseData['logo'] = $this->sizesForFranchise($franchise, $franchise->primaryMediaUse);
                }

                $squareLogoUse = $franchise->mediaUses
                    ->first(fn($mediaUse) => $mediaUse->flags['square'] ?? false);
                if ($squareLogoUse) {
                    $franchiseData['square_logo'] = $this->sizesForFranchise($franchise, $squareLogoUse);
                }

                if (Settings::get('crm-calltracks-enabled')) {
                    $franchiseData['calltracks'] = !empty($franchise->data['crm-calltracks-tags'])
                        ? $franchise->data['crm-calltracks-tags']
                        : Settings::get('crm-calltracks-tags');
                }

                $franchiseData['socials'] = $franchise->getFilteredSocials();

                return $franchiseData;
            })
            ->toArray();
    }

    protected function isFranchise(): bool
    {
        if (!$this->tenantIsAllowedFranchises() || empty($this->resource)) {
            return false;
        }

        if (!empty($this->resource->franchise_id)) {
            return true;
        }

        return $this->resource?->template?->slug === 'franchise';
    }

    protected function franchiseData(): ?array
    {
        if ($this->isFranchise() !== true) {
            return null;
        }

        $franchise = Franchise::query()
            ->with([
                'primaryMediaUse.media',
                'mediaUses.media',
                'menus',
                'make',
                'dealerships',
            ])
            ->find($this->resource->franchise_id);
        if (!$franchise) {
            return null;
        }
        $franchiseData = $franchise?->only([
            'id',
            'name',
            'slug',
            'logo',
            'primary_colour',
            'secondary_colour',
            'menus',
            'make_id',
        ]);

        if ($franchise->primaryMediaUse) {
            $franchiseData['logo'] = $this->sizesForFranchise($franchise, $franchise->primaryMediaUse);
        }

        $squareLogoUse = $franchise->mediaUses
            ->first(fn($mediaUse) => $mediaUse->flags['square'] ?? false);
        if ($squareLogoUse) {
            $franchiseData['square_logo'] = $this->sizesForFranchise($franchise, $squareLogoUse);
        }

        $franchiseData['menus'] = $franchise->menus->map(fn(Menu $menu) => new MenuResource($menu));
        $franchiseData['make_slug'] = $franchise->make?->slug;

        if (Settings::get('crm-calltracks-enabled')) {
            $franchiseData['calltracks'] = !empty($franchise->data['crm-calltracks-tags'])
                ? $franchise->data['crm-calltracks-tags']
                : Settings::get('crm-calltracks-tags');
        }

        $franchiseData['socials'] = $franchise->getFilteredSocials();

        return $franchiseData;
    }


    protected function getFranchiseId(): int
    {
        return 0;
    }

    protected function tenantIsAllowedFranchises(): bool
    {
        return Feature::isEnabled('franchises') && TierHelper::isAllowed(tenant()->tier, 'pro');
    }

    private function sizesForFranchise(Model $model, MediaUse $mediaUse): Collection
    {
        return MediaSize::query()
            ->where('model', $mediaUse->getOwnerType())
            ->get()
            ->keyBy('label')
            ->map(fn(MediaSize $size) => $mediaUse->getUrl($size->label))
            ->put('original', $mediaUse->media->getOriginalUrlAttribute());
    }
}
