<?php

namespace App\Services\Quote;

use App\Models\Quote\Quote;
use App\Services\NumberingService;
use App\Services\Service;

class QuoteNumberService extends Service
{
    public function __construct(
        private NumberingService $numberingService
    ) {}

    /**
     * 견적번호 생성
     *
     * 채번규칙이 있으면 NumberingService 사용, 없으면 레거시 로직
     */
    public function generate(?string $productCategory = null): string
    {
        $this->numberingService->setContext(
            $this->tenantId(),
            $this->apiUserId()
        );

        $number = $this->numberingService->generate('quote', [
            'product_category' => $productCategory,
        ]);

        if ($number !== null) {
            return $number;
        }

        return $this->generateLegacy($productCategory);
    }

    /**
     * 기본 견적번호 생성
     *
     * 형식: QT{YYYYMMDD}{NNNN}
     * 예시: QT202602070001
     */
    private function generateLegacy(?string $productCategory = null): string
    {
        $tenantId = $this->tenantId();
        $prefix = 'QT';
        $date = now()->format('Ymd');

        $lastNo = Quote::withTrashed()
            ->where('tenant_id', $tenantId)
            ->where('quote_number', 'like', "{$prefix}{$date}%")
            ->orderByDesc('quote_number')
            ->value('quote_number');

        if ($lastNo) {
            $seq = (int) substr($lastNo, -4) + 1;
        } else {
            $seq = 1;
        }

        return sprintf('%s%s%04d', $prefix, $date, $seq);
    }

    /**
     * 견적번호 미리보기
     */
    public function preview(?string $productCategory = null): array
    {
        $this->numberingService->setContext(
            $this->tenantId(),
            $this->apiUserId()
        );

        $rulePreview = $this->numberingService->preview('quote', [
            'product_category' => $productCategory,
        ]);

        if ($rulePreview !== null) {
            return [
                'quote_number' => $rulePreview['preview_number'],
                'product_category' => $productCategory ?? Quote::CATEGORY_SCREEN,
                'rule_name' => $rulePreview['rule_name'],
                'generated_at' => now()->toDateTimeString(),
            ];
        }

        $quoteNumber = $this->generateLegacy($productCategory);

        return [
            'quote_number' => $quoteNumber,
            'product_category' => $productCategory ?? Quote::CATEGORY_SCREEN,
            'generated_at' => now()->toDateTimeString(),
        ];
    }

    /**
     * 견적번호 형식 검증
     *
     * 지원 형식:
     * - 기본: QT{YYYYMMDD}{NNNN} (예: QT202602070001)
     * - 채번규칙: KD-PR-{YYMMDD}-{NN} (예: KD-PR-260207-01)
     */
    public function validate(string $quoteNumber): bool
    {
        return (bool) preg_match('/^(QT\d{8}\d{4,}|KD-[A-Z]{2}-\d{6}-\d{2,})$/', $quoteNumber);
    }

    /**
     * 견적번호 파싱
     */
    public function parse(string $quoteNumber): ?array
    {
        if (! $this->validate($quoteNumber)) {
            return null;
        }

        // 채번규칙 형식: KD-PR-260207-01
        if (str_starts_with($quoteNumber, 'KD-')) {
            $parts = explode('-', $quoteNumber);

            return [
                'prefix' => $parts[0],
                'category_code' => $parts[1],
                'date' => $parts[2],
                'sequence' => (int) $parts[3],
            ];
        }

        // 기본 형식: QT202602070001
        return [
            'prefix' => 'QT',
            'date' => substr($quoteNumber, 2, 8),
            'sequence' => (int) substr($quoteNumber, 10),
        ];
    }

    /**
     * 견적번호 중복 체크
     */
    public function isUnique(string $quoteNumber, ?int $excludeId = null): bool
    {
        $tenantId = $this->tenantId();

        $query = Quote::withTrashed()
            ->where('tenant_id', $tenantId)
            ->where('quote_number', $quoteNumber);

        if ($excludeId) {
            $query->where('id', '!=', $excludeId);
        }

        return ! $query->exists();
    }
}
