<?php

namespace App\Services\Sales;

use App\Models\Sales\BusinessCardRequest;

class BusinessCardRequestService
{
    /**
     * 뱃지용 대기 건수 (요청 + 제작의뢰)
     */
    public function getPendingCount(): int
    {
        $tenantId = session('selected_tenant_id', 1);

        return BusinessCardRequest::ofTenant($tenantId)
            ->whereIn('status', [BusinessCardRequest::STATUS_PENDING, BusinessCardRequest::STATUS_ORDERED])
            ->count();
    }

    /**
     * 통계
     */
    public function getStats(): array
    {
        $tenantId = session('selected_tenant_id', 1);
        $base = BusinessCardRequest::ofTenant($tenantId);

        return [
            'pending' => (clone $base)->pending()->count(),
            'ordered' => (clone $base)->ordered()->count(),
            'processed_today' => (clone $base)->processed()
                ->whereDate('processed_at', today())
                ->count(),
            'total' => (clone $base)->count(),
        ];
    }

    /**
     * 신규 요청 목록
     */
    public function getPendingRequests(?string $search = null, int $perPage = 20)
    {
        return $this->buildQuery(BusinessCardRequest::STATUS_PENDING, $search)
            ->with('requester')
            ->latest()
            ->paginate($perPage, ['*'], 'pending_page');
    }

    /**
     * 제작의뢰 목록
     */
    public function getOrderedRequests(?string $search = null, int $perPage = 20)
    {
        return $this->buildQuery(BusinessCardRequest::STATUS_ORDERED, $search)
            ->with(['requester', 'orderer'])
            ->latest('ordered_at')
            ->paginate($perPage, ['*'], 'ordered_page');
    }

    /**
     * 처리완료 목록
     */
    public function getProcessedRequests(?string $search = null, int $perPage = 20)
    {
        return $this->buildQuery(BusinessCardRequest::STATUS_PROCESSED, $search)
            ->with(['requester', 'processor'])
            ->latest('processed_at')
            ->paginate($perPage, ['*'], 'processed_page');
    }

    /**
     * 내 신청 이력
     */
    public function getMyRequests(int $userId, int $perPage = 20)
    {
        $tenantId = session('selected_tenant_id', 1);

        return BusinessCardRequest::ofTenant($tenantId)
            ->where('user_id', $userId)
            ->with('processor')
            ->latest()
            ->paginate($perPage);
    }

    /**
     * 신청 생성
     */
    public function createRequest(array $data): BusinessCardRequest
    {
        $data['tenant_id'] = session('selected_tenant_id', 1);
        $data['user_id'] = auth()->id();
        $data['status'] = BusinessCardRequest::STATUS_PENDING;

        return BusinessCardRequest::create($data);
    }

    /**
     * 제작의뢰
     */
    public function order(int $id): BusinessCardRequest
    {
        $tenantId = session('selected_tenant_id', 1);
        $request = BusinessCardRequest::ofTenant($tenantId)->findOrFail($id);
        $request->markAsOrdered(auth()->id());

        return $request;
    }

    /**
     * 처리 완료
     */
    public function process(int $id, ?string $memo = null): BusinessCardRequest
    {
        $tenantId = session('selected_tenant_id', 1);
        $request = BusinessCardRequest::ofTenant($tenantId)->findOrFail($id);
        $request->markAsProcessed(auth()->id(), $memo);

        return $request;
    }

    /**
     * 처리완료 건 삭제
     */
    public function delete(int $id): void
    {
        $tenantId = session('selected_tenant_id', 1);
        $request = BusinessCardRequest::ofTenant($tenantId)->findOrFail($id);

        if ($request->status !== BusinessCardRequest::STATUS_PROCESSED) {
            abort(422, '처리완료 상태만 삭제할 수 있습니다.');
        }

        $request->delete();
    }

    private function buildQuery(string $status, ?string $search)
    {
        $tenantId = session('selected_tenant_id', 1);
        $query = BusinessCardRequest::ofTenant($tenantId)->where('status', $status);

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('phone', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%");
            });
        }

        return $query;
    }
}
