<?php

namespace App\Repositories\Username\Write;

use App\enum\UsernameType;
use App\Models\Username;
use App\Repositories\WriteRepository;

class UsernameWriteRepository extends WriteRepository
{
    protected function getCacheTag(): string
    {
        return 'usernames';
    }

    protected function getReadRepositoryClass(): string
    {
        return \App\Repositories\Username\Read\UsernameReadRepository::class;
    }

    public function activateUsername(Username $username): bool
    {
        $username->is_active = true;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function deactivateUsername(Username $username): bool
    {
        $username->is_active = false;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function updateUsage(Username $username): bool
    {
        $username->last_used_at = now();
        $username->checked_at = now();
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function updateCheckedAt(Username $username): bool
    {
        $username->checked_at = now();
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function setExpiration(Username $username, ?\DateTime $endsAt = null): bool
    {
        $username->ends_at = $endsAt;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function setStartDate(Username $username, ?\DateTime $startsAt = null): bool
    {
        $username->starts_at = $startsAt;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function changeType(Username $username, UsernameType $type): bool
    {
        $username->username_type = $type->value;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function bulkActivate(array $usernameIds): int
    {
        $updated = Username::whereIn('id', $usernameIds)->update(['is_active' => true]);
        $this->clearCache();

        return $updated;
    }

    public function bulkDeactivate(array $usernameIds): int
    {
        $updated = Username::whereIn('id', $usernameIds)->update(['is_active' => false]);
        $this->clearCache();

        return $updated;
    }

    public function updateDailyMailboxLimit(Username $username, int $limit): bool
    {
        $username->daily_mailbox_limit = $limit;
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function createWithDefaults(array $data): Username
    {
        $defaults = [
            'is_active' => true,
            'daily_mailbox_limit' => 100,
            'checked_at' => now(),
        ];

        $usernameData = array_merge($defaults, $data);

        return $this->create($usernameData);
    }

    public function markAsUsed(Username $username): bool
    {
        $username->last_used_at = now();
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function resetUsage(Username $username): bool
    {
        $username->last_used_at = null;
        $username->checked_at = now();
        $result = $username->save();
        $this->clearRelatedCache($username);

        return $result;
    }

    public function bulkUpdateUsage(array $usernameIds): int
    {
        $updated = Username::whereIn('id', $usernameIds)->update([
            'last_used_at' => now(),
            'checked_at' => now(),
        ]);
        $this->clearCache();

        return $updated;
    }

    public function bulkResetUsage(array $usernameIds): int
    {
        $updated = Username::whereIn('id', $usernameIds)->update([
            'last_used_at' => null,
            'checked_at' => now(),
        ]);
        $this->clearCache();

        return $updated;
    }
}
