<?php

namespace App\Repositories\Cs;

use App\Models\GcBoard;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;

final class NoticeRepository
{
    private function baseVisible(): Builder
    {
        // 기존 스코프 유지 (gubun=notice + hiding=N 등)
        return GcBoard::query()->visibleNotice();
    }

    public function paginate(string $q, int $perPage = 15): LengthAwarePaginator
    {
        $q = trim($q);

        $query = $this->baseVisible()
            ->when($q !== '', function (Builder $query) use ($q) {
                $query->where(function (Builder $w) use ($q) {
                    $w->where('subject', 'like', "%{$q}%")
                        ->orWhere('content', 'like', "%{$q}%");
                });
            });

        // 기존 정렬 스코프 유지
        $query->noticeOrder();

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

    public function findOrFail(int $seq): GcBoard
    {
        return $this->baseVisible()
            ->where('seq', $seq)
            ->firstOrFail();
    }

    public function incrementHit(int $seq): void
    {
        // 단순 hit 증가
        GcBoard::query()
            ->where('seq', $seq)
            ->increment('hit');
    }

    /**
     * 리스트 정렬 기준(공지 우선 + 최신 우선)을 아래처럼 가정/고정:
     * 1) first_sign DESC
     * 2) seq DESC
     *
     * ⚠️ 기존 noticeOrder()가 regdate를 포함해도 무방하지만,
     * prev/next는 "가장 가까운 글"을 잡아야 해서 여기서는 명시적으로 처리.
     */
    public function findPrev(GcBoard $cur): ?GcBoard
    {
        $curFirst = (int)($cur->first_sign ?? 0);
        $curSeq   = (int)$cur->seq;

        return $this->baseVisible()
            ->where(function (Builder $w) use ($curFirst, $curSeq) {
                // COALESCE(first_sign,0) < curFirst
                $w->whereRaw('COALESCE(first_sign,0) < ?', [$curFirst])
                    ->orWhere(function (Builder $w2) use ($curFirst, $curSeq) {
                        // COALESCE(first_sign,0) = curFirst AND seq < curSeq
                        $w2->whereRaw('COALESCE(first_sign,0) = ?', [$curFirst])
                            ->where('seq', '<', $curSeq);
                    });
            })
            ->orderByRaw('COALESCE(first_sign,0) desc')
            ->orderBy('seq', 'desc')
            ->first();
    }

    public function findNext(GcBoard $cur): ?GcBoard
    {
        $curFirst = (int)($cur->first_sign ?? 0);
        $curSeq   = (int)$cur->seq;

        // "가장 가까운 앞"을 위해 ASC로 뒤집어서 first()
        return $this->baseVisible()
            ->where(function (Builder $w) use ($curFirst, $curSeq) {
                $w->whereRaw('COALESCE(first_sign,0) > ?', [$curFirst])
                    ->orWhere(function (Builder $w2) use ($curFirst, $curSeq) {
                        $w2->whereRaw('COALESCE(first_sign,0) = ?', [$curFirst])
                            ->where('seq', '>', $curSeq);
                    });
            })
            ->orderByRaw('COALESCE(first_sign,0) asc')
            ->orderBy('seq', 'asc')
            ->first();
    }
}
