<?php

namespace App\Services\Bidding;

use App\Models\Bidding\Bidding;
use App\Services\Service;
use Illuminate\Pagination\LengthAwarePaginator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class BiddingService extends Service
{
    /**
     * 입찰 목록 조회 (페이지네이션, 필터링)
     */
    public function index(array $params): LengthAwarePaginator
    {
        $tenantId = $this->tenantId();

        $query = Bidding::where('tenant_id', $tenantId)
            ->with(['quote:id,quote_number']);

        // 상태 필터
        if (! empty($params['status'])) {
            $query->where('status', $params['status']);
        }

        // 날짜 범위 필터
        if (! empty($params['from_date'])) {
            $query->where('bidding_date', '>=', $params['from_date']);
        }
        if (! empty($params['to_date'])) {
            $query->where('bidding_date', '<=', $params['to_date']);
        }

        // 검색 (입찰번호, 거래처명, 현장명, 입찰자명)
        if (! empty($params['search'])) {
            $keyword = $params['search'];
            $query->where(function ($q) use ($keyword) {
                $q->where('bidding_code', 'like', "%{$keyword}%")
                    ->orWhere('client_name', 'like', "%{$keyword}%")
                    ->orWhere('project_name', 'like', "%{$keyword}%")
                    ->orWhere('bidder_name', 'like', "%{$keyword}%");
            });
        }

        // 정렬
        $sortBy = $params['sort_by'] ?? 'bidding_date';
        $sortDir = $params['sort_dir'] ?? 'desc';
        $query->orderBy($sortBy, $sortDir);

        // 페이지네이션 (최대 100개로 제한)
        $perPage = min($params['per_page'] ?? 20, 100);

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

    /**
     * 입찰 생성 (견적에서 전환 포함)
     */
    public function store(array $data): Bidding
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        // 견적에서 전환하는 경우, 이미 입찰이 등록되었는지 체크
        if (! empty($data['quote_id'])) {
            $existingBidding = Bidding::where('tenant_id', $tenantId)
                ->where('quote_id', $data['quote_id'])
                ->first();

            if ($existingBidding) {
                throw new \Symfony\Component\HttpKernel\Exception\ConflictHttpException(
                    __('error.bidding.already_registered', ['code' => $existingBidding->bidding_code])
                );
            }
        }

        // 입찰번호 자동 생성
        $biddingCode = $this->generateBiddingCode($tenantId);

        $bidding = Bidding::create([
            'tenant_id' => $tenantId,
            'bidding_code' => $biddingCode,
            'quote_id' => $data['quote_id'] ?? null,
            // 거래처/현장
            'client_id' => $data['client_id'] ?? null,
            'client_name' => $data['client_name'] ?? null,
            'project_name' => $data['project_name'],
            // 입찰 정보
            'bidding_date' => $data['bidding_date'] ?? now()->toDateString(),
            'bid_date' => $data['bid_date'] ?? null,
            'submission_date' => $data['submission_date'] ?? null,
            'confirm_date' => $data['confirm_date'] ?? null,
            'total_count' => $data['total_count'] ?? 0,
            'bidding_amount' => $data['bidding_amount'] ?? 0,
            // 상태 (기본값: waiting)
            'status' => $data['status'] ?? Bidding::STATUS_WAITING,
            // 입찰자
            'bidder_id' => $data['bidder_id'] ?? null,
            'bidder_name' => $data['bidder_name'] ?? null,
            // 공사기간
            'construction_start_date' => $data['construction_start_date'] ?? null,
            'construction_end_date' => $data['construction_end_date'] ?? null,
            'vat_type' => $data['vat_type'] ?? Bidding::VAT_EXCLUDED,
            // 비고
            'remarks' => $data['remarks'] ?? null,
            // 견적 데이터 스냅샷
            'expense_items' => $data['expense_items'] ?? null,
            'estimate_detail_items' => $data['estimate_detail_items'] ?? null,
            // 감사
            'created_by' => $userId,
        ]);

        return $bidding->load(['quote:id,quote_number']);
    }

    /**
     * 입찰번호 자동 생성 (BID-YYYY-NNN)
     */
    private function generateBiddingCode(int $tenantId): string
    {
        $year = now()->year;
        $prefix = "BID-{$year}-";

        // 올해 생성된 마지막 입찰번호 조회
        $lastBidding = Bidding::where('tenant_id', $tenantId)
            ->where('bidding_code', 'like', "{$prefix}%")
            ->orderBy('bidding_code', 'desc')
            ->first();

        if ($lastBidding) {
            // 마지막 번호에서 숫자 추출 후 +1
            $lastNumber = (int) substr($lastBidding->bidding_code, -3);
            $nextNumber = $lastNumber + 1;
        } else {
            $nextNumber = 1;
        }

        return $prefix.str_pad($nextNumber, 3, '0', STR_PAD_LEFT);
    }

    /**
     * 입찰 통계 조회
     */
    public function stats(): array
    {
        $tenantId = $this->tenantId();

        return [
            'total' => Bidding::where('tenant_id', $tenantId)->count(),
            'waiting' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_WAITING)->count(),
            'submitted' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_SUBMITTED)->count(),
            'awarded' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_AWARDED)->count(),
            'failed' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_FAILED)->count(),
            'invalid' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_INVALID)->count(),
            'hold' => Bidding::where('tenant_id', $tenantId)->where('status', Bidding::STATUS_HOLD)->count(),
        ];
    }

    /**
     * 입찰 단건 조회
     */
    public function show(int $id): Bidding
    {
        $tenantId = $this->tenantId();

        $bidding = Bidding::where('tenant_id', $tenantId)
            ->with(['quote:id,quote_number,site_name,total_amount,status'])
            ->find($id);

        if (! $bidding) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        return $bidding;
    }

    /**
     * 입찰 수정
     */
    public function update(int $id, array $data): Bidding
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $bidding = Bidding::where('tenant_id', $tenantId)->find($id);

        if (! $bidding) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $data['updated_by'] = $userId;
        $bidding->update($data);

        return $bidding->fresh(['quote:id,quote_number']);
    }

    /**
     * 입찰 삭제 (소프트 삭제)
     */
    public function destroy(int $id): bool
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $bidding = Bidding::where('tenant_id', $tenantId)->find($id);

        if (! $bidding) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $bidding->update(['deleted_by' => $userId]);
        $bidding->delete();

        return true;
    }

    /**
     * 입찰 일괄 삭제
     */
    public function bulkDestroy(array $ids): int
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $biddings = Bidding::where('tenant_id', $tenantId)
            ->whereIn('id', $ids)
            ->get();

        $deletedCount = 0;
        foreach ($biddings as $bidding) {
            $bidding->update(['deleted_by' => $userId]);
            $bidding->delete();
            $deletedCount++;
        }

        return $deletedCount;
    }

    /**
     * 입찰 상태 변경
     */
    public function updateStatus(int $id, string $status): Bidding
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $bidding = Bidding::where('tenant_id', $tenantId)->find($id);

        if (! $bidding) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $bidding->update([
            'status' => $status,
            'updated_by' => $userId,
        ]);

        return $bidding->fresh(['quote:id,quote_number']);
    }
}
