<?php

namespace App\Repositories\Admin\Notice;

use App\Models\GcBoard;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

final class AdminNoticeRepository
{
    private const GUBUN = 'notice';

    public function paginate(array $filters, int $perPage = 15): LengthAwarePaginator
    {
        $q     = trim((string)($filters['q'] ?? ''));
        $field = (string)($filters['field'] ?? 'subject');
        if (!in_array($field, ['subject', 'content'], true)) $field = 'subject';

        $query = GcBoard::query()
            ->select(['seq','gubun','subject','admin_num','regdate','hiding','first_sign','hit'])
            ->where('gubun', self::GUBUN);

        if ($q !== '') {
            $query->where($field, 'like', '%'.$q.'%');
        }

        // ✅ 상단공지 먼저 + 최신순
        $query->orderByDesc('first_sign')
            ->orderByDesc('regdate')
            ->orderByDesc('seq');

        return $query->paginate($perPage);
    }

    public function findOrFailForEdit(int $id): GcBoard
    {
        return GcBoard::query()->whereKey($id)->firstOrFail();
    }

    public function lockForUpdate(int $id): GcBoard
    {
        return GcBoard::query()->lockForUpdate()->whereKey($id)->firstOrFail();
    }

    public function maxFirstSignForUpdate(): int
    {
        // notice 대상 max(first_sign) (동시성 대비 lock)
        $max = (int) (GcBoard::query()
            ->where('gubun', self::GUBUN)
            ->lockForUpdate()
            ->max('first_sign') ?? 0);

        return $max;
    }

    public function create(array $data): GcBoard
    {
        return GcBoard::query()->create($data);
    }

    public function update(GcBoard $row, array $data): bool
    {
        return $row->fill($data)->save();
    }

    public function delete(GcBoard $row): bool
    {
        return (bool) $row->delete();
    }

    public function transaction(\Closure $fn)
    {
        return DB::connection((new GcBoard)->getConnectionName())->transaction($fn);
    }
}
