<?php

namespace App\Repositories;

use App\Contracts\UserRepositoryInterface;
use App\DTO\UserDTO;
use App\Models\User;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Hash;

class UserRepository implements UserRepositoryInterface
{
    public function findById(int $id): ?User
    {
        return User::with(['role', 'shift'])->find($id);
    }

    public function findByEmail(string $email): ?User
    {
        return User::with(['role', 'shift'])->where('email', $email)->first();
    }

    public function getPaginatedUsers(string $search = '', ?int $roleId = null, int $perPage = 10): LengthAwarePaginator
    {
        return User::with(['role', 'shift'])
            ->when($search !== '', function ($query) use ($search) {
                $query->where(function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                        ->orWhere('email', 'like', "%{$search}%")
                        ->orWhere('nip_nis', 'like', "%{$search}%")
                        ->orWhere('class_name', 'like', "%{$search}%");
                });
            })
            ->when($roleId !== null, function ($query) use ($roleId) {
                $query->where('role_id', $roleId);
            })
            ->latest()
            ->paginate($perPage);
    }

    public function create(UserDTO $userDTO): User
    {
        return User::create([
            'role_id' => $userDTO->roleId,
            'shift_id' => $userDTO->shiftId,
            'name' => $userDTO->name,
            'nip_nis' => $userDTO->nipNis,
            'class_name' => $userDTO->className,
            'email' => $userDTO->email,
            'password' => Hash::make($userDTO->password ?? 'password123'),
            'force_password_change' => $userDTO->forcePasswordChange,
            'is_active' => $userDTO->isActive,
            'photo_path' => $userDTO->photoPath,
        ]);
    }

    public function update(int $id, UserDTO $userDTO): User
    {
        $user = User::findOrFail($id);

        $payload = [
            'role_id' => $userDTO->roleId,
            'shift_id' => $userDTO->shiftId,
            'name' => $userDTO->name,
            'nip_nis' => $userDTO->nipNis,
            'class_name' => $userDTO->className,
            'email' => $userDTO->email,
            'is_active' => $userDTO->isActive,
        ];

        if ($userDTO->password !== null && $userDTO->password !== '') {
            $payload['password'] = Hash::make($userDTO->password);
            $payload['force_password_change'] = $userDTO->forcePasswordChange;
        }

        if ($userDTO->photoPath !== null) {
            $payload['photo_path'] = $userDTO->photoPath;
        }

        $user->update($payload);

        return $user->fresh(['role', 'shift']);
    }

    public function updatePassword(User $user, string $hashedPassword, bool $forcePasswordChange = false): bool
    {
        return $user->update([
            'password' => $hashedPassword,
            'force_password_change' => $forcePasswordChange,
        ]);
    }

    public function toggleActiveStatus(User $user): bool
    {
        return $user->update([
            'is_active' => !$user->is_active,
        ]);
    }

    public function delete(int $id): bool
    {
        $user = User::findOrFail($id);
        return (bool) $user->delete();
    }
}
