<?php

namespace App\Services\Auth;

use App\Models\Company;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Hash;

class TenantLoginResolver
{
    /**
     * Resolve a login user by email (+ optional company) and password.
     * Without company: among all users with that email whose password matches,
     * return the user only when there is exactly one match.
     */
    public function findUserByEmailAndPassword(?string $companyKey, string $email, string $password): ?User
    {
        $matches = $this->passwordMatches($companyKey, $email, $password);

        return $matches->count() === 1 ? $matches->first() : null;
    }

    /**
     * True when more than one account shares this email and password.
     */
    public function hasMultiplePasswordMatches(?string $companyKey, string $email, string $password): bool
    {
        return $this->passwordMatches($companyKey, $email, $password)->count() > 1;
    }

    /**
     * Resolve a user for password-reset (email only / optional company).
     * Does not use the password.
     */
    public function findUser(?string $companyKey, string $email): ?User
    {
        $email = strtolower(trim($email));
        if ($email === '') {
            return null;
        }

        $companyKey = trim((string) $companyKey);
        if ($companyKey !== '') {
            $company = Company::findByShortName($companyKey);
            if (! $company) {
                return null;
            }

            return User::query()
                ->where('company_id', $company->id)
                ->where('email', $email)
                ->first();
        }

        $matches = User::query()->where('email', $email)->get();

        return $matches->count() === 1 ? $matches->first() : null;
    }

    /**
     * Credentials for Laravel Password broker (email + company_id).
     *
     * @return array{email: string, company_id: int|null}|null
     */
    public function passwordResetCredentials(?string $companyKey, string $email): ?array
    {
        $user = $this->findUser($companyKey, $email);
        if (! $user) {
            return null;
        }

        return [
            'email' => $user->email,
            'company_id' => $user->company_id,
        ];
    }

    /**
     * @return Collection<int, User>
     */
    private function passwordMatches(?string $companyKey, string $email, string $password): Collection
    {
        $email = strtolower(trim($email));
        if ($email === '' || $password === '') {
            return collect();
        }

        $query = User::query()->where('email', $email);

        $companyKey = trim((string) $companyKey);
        if ($companyKey !== '') {
            $company = Company::findByShortName($companyKey);
            if (! $company) {
                return collect();
            }
            $query->where('company_id', $company->id);
        }

        return $query->get()->filter(
            fn (User $user) => Hash::check($password, (string) $user->password)
        )->values();
    }
}
