<?php

namespace App\Support;

use App\Models\Site;
use App\Models\Transaction;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;

class SiteCredentialResolver
{
    public static function resolveByCredentials(?string $sid, ?string $apiKey = null): ?Site
    {
        $sid = trim((string) $sid);
        $apiKey = trim((string) $apiKey);

        if ($sid !== '' && $apiKey !== '') {
            $exact = Site::where('sid', $sid)->where('api_key', $apiKey)->first();
            if ($exact) {
                return $exact;
            }
        }

        if ($sid !== '') {
            $bySid = Site::where('sid', $sid)->first();
            if ($bySid) {
                return $bySid;
            }
        }

        if ($apiKey !== '') {
            $byKey = Site::where('api_key', $apiKey)->first();
            if ($byKey) {
                return $byKey;
            }
        }

        return null;
    }

    public static function resolveBySingleCredential(?string $credential): ?Site
    {
        $credential = trim((string) $credential);
        if ($credential === '') {
            return null;
        }

        return Site::where('sid', $credential)
            ->orWhere('api_key', $credential)
            ->first();
    }

    public static function resolveForTransaction(Transaction $transaction, ?Collection $sites = null): ?Site
    {
        if ($transaction->relationLoaded('site') && $transaction->site) {
            return $transaction->site;
        }

        if (!$sites) {
            $sites = Site::all();
        }

        if ($transaction->site_id) {
            $byId = $sites->firstWhere('id', $transaction->site_id);
            if ($byId) {
                return $byId;
            }
        }

        if ($transaction->sid) {
            $bySid = $sites->firstWhere('sid', $transaction->sid);
            if ($bySid) {
                return $bySid;
            }
        }

        if ($transaction->api_key) {
            $byKey = $sites->firstWhere('api_key', $transaction->api_key);
            if ($byKey) {
                return $byKey;
            }
        }

        return null;
    }

    public static function applySiteFilter(Builder $query, ?int $siteId): void
    {
        if (!$siteId) {
            return;
        }

        $site = Site::find($siteId);
        if (!$site) {
            $query->whereRaw('1 = 0');
            return;
        }

        $query->where(function (Builder $siteQuery) use ($site) {
            // Primary path: explicit site_id ownership
            $siteQuery->where('site_id', $site->id);

            // Legacy fallback: only rows without site_id can match by credentials
            $siteQuery->orWhere(function (Builder $legacyQuery) use ($site) {
                $legacyQuery->where(function (Builder $nullSiteQuery) {
                    $nullSiteQuery->whereNull('site_id')->orWhere('site_id', 0);
                });

                $legacyQuery->where(function (Builder $credentialQuery) use ($site) {
                    $hasCredential = false;

                    if (!empty($site->sid)) {
                        $credentialQuery->where('sid', $site->sid);
                        $hasCredential = true;
                    }

                    if (!empty($site->api_key)) {
                        if ($hasCredential) {
                            $credentialQuery->orWhere('api_key', $site->api_key);
                        } else {
                            $credentialQuery->where('api_key', $site->api_key);
                        }
                        $hasCredential = true;
                    }

                    if (!$hasCredential) {
                        $credentialQuery->whereRaw('1 = 0');
                    }
                });
            });
        });
    }
}
