<?php

namespace App\Services;

use App\Enums\UserTypeEnum;
use App\Models\Address;
use App\Models\Client;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class UserService
{
  public function me(): ?User
  {
    return User::with(['provider', 'client'])->find(Auth::id());
  }

  public function getAll(): Collection
  {
    return User::query()->orderBy("created_at", "desc")->get();
  }

  public function findById(int $id): ?User
  {
    return User::find($id);
  }

  public function create(array $data): User
  {
    return User::create($data);
  }

  public function update(int $id, array $data): ?User
  {
    $model = $this->findById($id);

    if (!$model) {
      return null;
    }

    $model->update($data);
    return $model->fresh();
  }

  public function delete(int $id): bool
  {
    $model = $this->findById($id);

    if (!$model) {
      return false;
    }

    return $model->delete();
  }

  public function updateMe(array $data): User
  {
    try {
      DB::beginTransaction();

      $user = User::with(['client'])->findOrFail(Auth::id());

      $userFields = array_filter(
        array_intersect_key($data, array_flip(['name', 'email', 'phone', 'language'])),
        fn($v) => $v !== null,
      );

      if (!empty($userFields)) {
        $user->update($userFields);
      }

      if (array_key_exists('document', $data)) {
        $client = $user->client ?? Client::create(['user_id' => $user->id]);
        $client->document = $data['document'];
        $client->save();
      }

      $user->load('client');

      $registrationComplete = !empty($user->name)
        && !empty($user->client?->document)
        && Address::where('source', 'client')->where('source_id', $user->client->id)->exists();

      if ($user->registration_complete !== $registrationComplete) {
        $user->registration_complete = $registrationComplete;
        $user->save();
      }

      DB::commit();
      return $user->fresh(['client']);
    } catch (\Exception $e) {
      DB::rollBack();
      Log::error('Erro ao atualizar perfil.', ['error' => $e->getMessage()]);
      throw $e;
    }
  }

  public function getUserTypes(): array
  {
    return UserTypeEnum::toArray();
  }
}
