<?php

namespace App\Services\Sales;

use App\Models\Sales\SalesTenantManagement;
use Illuminate\Pagination\LengthAwarePaginator;

/**
 * 개발 승인 관리 서비스
 * 영업/매니저 진행률이 100% 완료된 고객의 개발 진행 상태를 관리
 */
class SalesDevelopmentApprovalService
{
    /**
     * 통계 조회
     */
    public function getStats(): array
    {
        // 승인 대기 (영업 100% + 매니저 100% + hq_status = pending)
        $pendingCount = SalesTenantManagement::query()
            ->where('sales_progress', 100)
            ->where('manager_progress', 100)
            ->where('hq_status', SalesTenantManagement::HQ_STATUS_PENDING)
            ->count();

        // 개발 진행 중 (review ~ int_test)
        $progressStatuses = [
            SalesTenantManagement::HQ_STATUS_REVIEW,
            SalesTenantManagement::HQ_STATUS_PLANNING,
            SalesTenantManagement::HQ_STATUS_CODING,
            SalesTenantManagement::HQ_STATUS_DEV_TEST,
            SalesTenantManagement::HQ_STATUS_DEV_DONE,
            SalesTenantManagement::HQ_STATUS_INT_TEST,
        ];
        $inProgressCount = SalesTenantManagement::query()
            ->where('sales_progress', 100)
            ->where('manager_progress', 100)
            ->whereIn('hq_status', $progressStatuses)
            ->count();

        // 오늘 완료 (handover 상태이고 오늘 업데이트된)
        $todayCompletedCount = SalesTenantManagement::query()
            ->where('hq_status', SalesTenantManagement::HQ_STATUS_HANDOVER)
            ->whereDate('updated_at', today())
            ->count();

        // 총 완료
        $totalCompletedCount = SalesTenantManagement::query()
            ->where('hq_status', SalesTenantManagement::HQ_STATUS_HANDOVER)
            ->count();

        return [
            'pending' => $pendingCount,
            'in_progress' => $inProgressCount,
            'today_completed' => $todayCompletedCount,
            'total_completed' => $totalCompletedCount,
        ];
    }

    /**
     * 승인 대기 목록 조회
     */
    public function getPendingApprovals(?string $search = null, int $perPage = 10): LengthAwarePaginator
    {
        $query = SalesTenantManagement::query()
            ->with(['tenant', 'tenantProspect.registeredBy', 'salesPartner.user', 'manager'])
            ->where('sales_progress', 100)
            ->where('manager_progress', 100)
            ->where('hq_status', SalesTenantManagement::HQ_STATUS_PENDING);

        // 검색
        if ($search) {
            $query->whereHas('tenant', function ($q) use ($search) {
                $q->where('company_name', 'like', "%{$search}%")
                    ->orWhere('business_number', 'like', "%{$search}%");
            });
        }

        return $query->latest('updated_at')->paginate($perPage, ['*'], 'pending_page');
    }

    /**
     * 개발 진행 중 목록 조회
     */
    public function getInProgressItems(?string $search = null, int $perPage = 10): LengthAwarePaginator
    {
        $progressStatuses = [
            SalesTenantManagement::HQ_STATUS_REVIEW,
            SalesTenantManagement::HQ_STATUS_PLANNING,
            SalesTenantManagement::HQ_STATUS_CODING,
            SalesTenantManagement::HQ_STATUS_DEV_TEST,
            SalesTenantManagement::HQ_STATUS_DEV_DONE,
            SalesTenantManagement::HQ_STATUS_INT_TEST,
        ];

        $query = SalesTenantManagement::query()
            ->with(['tenant', 'tenantProspect.registeredBy', 'salesPartner.user', 'manager'])
            ->where('sales_progress', 100)
            ->where('manager_progress', 100)
            ->whereIn('hq_status', $progressStatuses);

        // 검색
        if ($search) {
            $query->whereHas('tenant', function ($q) use ($search) {
                $q->where('company_name', 'like', "%{$search}%")
                    ->orWhere('business_number', 'like', "%{$search}%");
            });
        }

        return $query->latest('updated_at')->paginate($perPage, ['*'], 'progress_page');
    }

    /**
     * 완료 목록 조회
     */
    public function getCompletedItems(?string $search = null, int $perPage = 10): LengthAwarePaginator
    {
        $query = SalesTenantManagement::query()
            ->with(['tenant', 'tenantProspect.registeredBy', 'salesPartner.user', 'manager'])
            ->where('hq_status', SalesTenantManagement::HQ_STATUS_HANDOVER);

        // 검색
        if ($search) {
            $query->whereHas('tenant', function ($q) use ($search) {
                $q->where('company_name', 'like', "%{$search}%")
                    ->orWhere('business_number', 'like', "%{$search}%");
            });
        }

        return $query->latest('updated_at')->paginate($perPage, ['*'], 'completed_page');
    }

    /**
     * 개발 승인 처리 (pending → review)
     */
    public function approve(int $id): SalesTenantManagement
    {
        $management = SalesTenantManagement::findOrFail($id);

        // 승인 조건 확인
        if ($management->sales_progress < 100 || $management->manager_progress < 100) {
            throw new \InvalidArgumentException('영업/매니저 진행률이 100%가 아닙니다.');
        }

        if ($management->hq_status !== SalesTenantManagement::HQ_STATUS_PENDING) {
            throw new \InvalidArgumentException('이미 승인된 항목입니다.');
        }

        $management->update([
            'hq_status' => SalesTenantManagement::HQ_STATUS_REVIEW,
        ]);

        return $management->fresh();
    }

    /**
     * 반려 처리
     */
    public function reject(int $id, string $reason): SalesTenantManagement
    {
        $management = SalesTenantManagement::findOrFail($id);

        if ($management->hq_status !== SalesTenantManagement::HQ_STATUS_PENDING) {
            throw new \InvalidArgumentException('승인 대기 상태가 아닙니다.');
        }

        // notes 필드에 반려 사유 추가
        $currentNotes = $management->notes ?? '';
        $rejectionNote = '[반려 '.now()->format('Y-m-d H:i').'] '.$reason;
        $newNotes = $currentNotes ? $currentNotes."\n".$rejectionNote : $rejectionNote;

        $management->update([
            'notes' => $newNotes,
        ]);

        return $management->fresh();
    }

    /**
     * 본사 진행 상태 업데이트
     */
    public function updateHqStatus(int $id, string $status): SalesTenantManagement
    {
        $management = SalesTenantManagement::findOrFail($id);

        // 유효한 상태인지 확인
        if (! array_key_exists($status, SalesTenantManagement::$hqStatusLabels)) {
            throw new \InvalidArgumentException('유효하지 않은 상태입니다.');
        }

        // pending 상태에서는 review로만 변경 가능 (승인 처리)
        if ($management->hq_status === SalesTenantManagement::HQ_STATUS_PENDING && $status !== SalesTenantManagement::HQ_STATUS_REVIEW) {
            throw new \InvalidArgumentException('승인 대기 상태에서는 검토 상태로만 변경 가능합니다. 먼저 승인 처리를 해주세요.');
        }

        $management->update([
            'hq_status' => $status,
        ]);

        return $management->fresh();
    }

    /**
     * 승인대기로 되돌리기 (진행중 → pending)
     */
    public function revertToPending(int $id): SalesTenantManagement
    {
        $management = SalesTenantManagement::findOrFail($id);

        // 이미 pending 상태인 경우
        if ($management->hq_status === SalesTenantManagement::HQ_STATUS_PENDING) {
            throw new \InvalidArgumentException('이미 승인대기 상태입니다.');
        }

        // handover(인계) 상태에서는 되돌리기 불가
        if ($management->hq_status === SalesTenantManagement::HQ_STATUS_HANDOVER) {
            throw new \InvalidArgumentException('인계 완료된 항목은 되돌릴 수 없습니다.');
        }

        $management->update([
            'hq_status' => SalesTenantManagement::HQ_STATUS_PENDING,
        ]);

        return $management->fresh();
    }

    /**
     * 상세 정보 조회
     */
    public function getDetail(int $id): SalesTenantManagement
    {
        return SalesTenantManagement::with([
            'tenant',
            'tenantProspect',
            'salesPartner.user',
            'manager',
            'contractProducts.product',
        ])->findOrFail($id);
    }
}
