<?php

namespace App\Master\Http\Resources;

use App\TierHelper;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use JsonSerializable;
use Mtc\MercuryDataModels\Tenant;
use Symfony\Component\Intl\Currencies;

class SiteListResource extends JsonResource
{
    /**
     * @var LengthAwarePaginator
     */
    public $resource;

    private array $faviconCache = [];

    public function __construct($resource, private readonly array $favouriteSiteIds = [])
    {
        parent::__construct($resource);
    }

    /**
     * Transform the resource into an array.
     *
     * @param Request $request
     * @return array|Arrayable|JsonSerializable
     */
    #[\Override]
    public function toArray($request)
    {
        $this->preloadFavicons($this->resource->items());

        $this->resource = $this->resource
            ->through(fn ($site) => $this->siteDetails($site));

        $result = parent::toArray($request);
        $result['favourite_site_ids'] = $this->favouriteSiteIds;

        return $result;
    }

    /**
     * Batch-load favicons for all sites using direct DB queries,
     * avoiding full tenancy initialization per site. URLs are built via the
     * default media disk so they match what `Settings::get('site-favicon')`
     * returns under a tenant context.
     */
    private function preloadFavicons(array $sites): void
    {
        $dbPrefix = config('tenancy.database.prefix', 'tenant');
        $dbSuffix = config('tenancy.database.suffix', '');
        $mediaDisk = Config::get('filesystems.default_media', 'public');

        foreach ($sites as $site) {
            $dbName = $dbPrefix . $site->id . $dbSuffix;
            try {
                $setting = DB::select(
                    "SELECT `value` FROM `{$dbName}`.`settings`"
                    . " WHERE `config_key` = ? LIMIT 1",
                    ['site-favicon']
                );
                $path = $setting[0]->value ?? null;
                if (!empty($path)) {
                    $this->faviconCache[$site->id] = [
                        'path' => $path,
                        'url' => Storage::disk($mediaDisk)->url($path),
                    ];
                } else {
                    $this->faviconCache[$site->id] = $this->placeholder($site);
                }
            } catch (\Exception) {
                $this->faviconCache[$site->id] = $this->placeholder($site);
            }
        }
    }

    private function siteDetails(Tenant $site)
    {
        return [
            'id' => $site->id,
            'name' => $site->name,
            'icon' => $this->faviconCache[$site->id] ?? $this->placeholder($site),
            'is_suspended' => $site->is_suspended,
            'has_cloudflare' => $site->has_cloudflare,
            'is_live' => !empty($site->live_at),
            'proposed_launch_date' => $site->proposed_launch_date,
            'primary_domain' => $site->domains->where('primary', 1)->first()?->domain,
            'domains' => $site->domains->pluck('domain'),
            'tier' => $site->tier,
            'user_limit' => TierHelper::userLimit($site->tier),
            'currency' => Currencies::getSymbol($site->currency ?? 'GBP'),
            'features' => $site->features->pluck('feature'),
            'is_favourite' => in_array($site->id, $this->favouriteSiteIds),
            'users' => $site->users->map(fn ($user) => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'profile_photo_url' => $user->profile_photo_url,
                'role' => $user->pivot->role,
            ])
        ];
    }

    private function placeholder(Tenant $site)
    {
        return [
            'url' => 'https://ui-avatars.com/api/?name='
                . urlencode($site->name) . '&color=7F9CF5&background=EBF4FF'
        ];
    }
}
