<?php

namespace App\Services\Rd;

use App\Helpers\AiTokenHelper;
use App\Models\Rd\AiQuotation;
use App\Models\Rd\AiQuotationItem;
use App\Models\Rd\AiQuotationModule;
use App\Models\Rd\AiQuotePriceTable;
use App\Models\System\AiConfig;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class AiQuotationService
{
    /**
     * 목록 조회
     */
    public function getList(array $params = []): LengthAwarePaginator
    {
        $query = AiQuotation::query()
            ->with('creator:id,name')
            ->orderBy('created_at', 'desc');

        if (! empty($params['status'])) {
            $query->where('status', $params['status']);
        }

        if (! empty($params['search'])) {
            $search = $params['search'];
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('input_text', 'like', "%{$search}%");
            });
        }

        return $query->paginate($params['per_page'] ?? 10);
    }

    /**
     * 상세 조회
     */
    public function getById(int $id): ?AiQuotation
    {
        return AiQuotation::with(['items', 'creator:id,name'])->find($id);
    }

    /**
     * 견적 요청 생성 + AI 분석 실행
     */
    public function createAndAnalyze(array $data): array
    {
        $provider = $data['ai_provider'] ?? 'gemini';
        $quoteMode = $data['quote_mode'] ?? AiQuotation::MODE_MODULE;

        $quotation = AiQuotation::create([
            'tenant_id' => session('selected_tenant_id', 1),
            'quote_mode' => $quoteMode,
            'product_category' => $data['product_category'] ?? null,
            'title' => $data['title'],
            'input_type' => $data['input_type'] ?? 'text',
            'input_text' => $data['input_text'] ?? null,
            'ai_provider' => $provider,
            'status' => AiQuotation::STATUS_PENDING,
            'created_by' => Auth::id(),
        ]);

        // 제조 모드: 고객 정보를 options에 저장
        if ($quoteMode === AiQuotation::MODE_MANUFACTURE) {
            $quotation->update([
                'quote_number' => $this->generateQuoteNumber($data['product_category'] ?? 'SC'),
                'options' => array_filter([
                    'client' => array_filter([
                        'company' => $data['client_company'] ?? null,
                        'contact' => $data['client_contact'] ?? null,
                        'phone' => $data['client_phone'] ?? null,
                        'email' => $data['client_email'] ?? null,
                    ]),
                ]),
            ]);

            return $this->runManufactureAnalysis($quotation);
        }

        return $this->runAnalysis($quotation);
    }

    /**
     * AI 분석 실행 (재분석 가능)
     */
    public function runAnalysis(AiQuotation $quotation): array
    {
        try {
            $quotation->update(['status' => AiQuotation::STATUS_PROCESSING]);

            $provider = $quotation->ai_provider;
            $config = AiConfig::getActive($provider);

            if (! $config) {
                throw new \RuntimeException("{$provider} API 설정이 없습니다.");
            }

            // 1차 호출: 업무 분석
            $modules = AiQuotationModule::getActiveModulesForPrompt();
            $analysisPrompt = $this->buildAnalysisPrompt($quotation->input_text, $modules);
            $analysisRaw = $this->callAi($config, $provider, $analysisPrompt, 'AI견적-업무분석');

            $analysisResult = $this->parseJsonResponse($analysisRaw);
            if (! $analysisResult) {
                throw new \RuntimeException('AI 업무 분석 결과 파싱 실패');
            }

            $quotation->update(['analysis_result' => $analysisResult]);

            // 2차 호출: 견적 생성
            $quotationPrompt = $this->buildQuotationPrompt($analysisResult, $modules);
            $quotationRaw = $this->callAi($config, $provider, $quotationPrompt, 'AI견적-견적생성');

            $quotationResult = $this->parseJsonResponse($quotationRaw);
            if (! $quotationResult) {
                throw new \RuntimeException('AI 견적 생성 결과 파싱 실패');
            }

            // 추천 모듈 아이템 저장
            $this->saveQuotationItems($quotation, $quotationResult, $modules);

            // 합계 계산
            $totals = $quotation->items()->selectRaw(
                'SUM(dev_cost) as total_dev, SUM(monthly_fee) as total_monthly'
            )->first();

            $quotation->update([
                'quotation_result' => $quotationResult,
                'ai_model' => $config->model,
                'total_dev_cost' => $totals->total_dev ?? 0,
                'total_monthly_fee' => $totals->total_monthly ?? 0,
                'status' => AiQuotation::STATUS_COMPLETED,
            ]);

            return [
                'ok' => true,
                'quotation' => $quotation->fresh(['items', 'creator:id,name']),
            ];
        } catch (\Exception $e) {
            Log::error('AI 견적 분석 실패', [
                'quotation_id' => $quotation->id,
                'error' => $e->getMessage(),
            ]);

            $quotation->update(['status' => AiQuotation::STATUS_FAILED]);

            return [
                'ok' => false,
                'error' => $e->getMessage(),
                'quotation' => $quotation->fresh(),
            ];
        }
    }

    /**
     * AI API 호출 (Gemini / Claude)
     */
    private function callAi(AiConfig $config, string $provider, string $prompt, string $menuName): ?string
    {
        return match ($provider) {
            'gemini' => $this->callGemini($config, $prompt, $menuName),
            'claude' => $this->callClaude($config, $prompt, $menuName),
            default => throw new \RuntimeException("지원하지 않는 AI Provider: {$provider}"),
        };
    }

    /**
     * Gemini API 호출
     */
    private function callGemini(AiConfig $config, string $prompt, string $menuName): ?string
    {
        $model = $config->model;
        $apiKey = $config->api_key;
        $baseUrl = $config->base_url ?? 'https://generativelanguage.googleapis.com/v1beta';

        $url = "{$baseUrl}/models/{$model}:generateContent?key={$apiKey}";

        $response = Http::timeout(120)
            ->withHeaders(['Content-Type' => 'application/json'])
            ->post($url, [
                'contents' => [
                    ['parts' => [['text' => $prompt]]],
                ],
                'generationConfig' => [
                    'temperature' => 0.3,
                    'maxOutputTokens' => 8192,
                    'responseMimeType' => 'application/json',
                ],
            ]);

        if (! $response->successful()) {
            Log::error('Gemini API error', [
                'status' => $response->status(),
                'body' => $response->body(),
            ]);
            throw new \RuntimeException('Gemini API 호출 실패: '.$response->status());
        }

        $result = $response->json();

        AiTokenHelper::saveGeminiUsage($result, $result['modelVersion'] ?? $model, $menuName);

        return $result['candidates'][0]['content']['parts'][0]['text'] ?? null;
    }

    /**
     * Claude API 호출
     */
    private function callClaude(AiConfig $config, string $prompt, string $menuName): ?string
    {
        $response = Http::timeout(120)
            ->withHeaders([
                'x-api-key' => $config->api_key,
                'anthropic-version' => '2023-06-01',
                'content-type' => 'application/json',
            ])
            ->post($config->base_url.'/messages', [
                'model' => $config->model,
                'max_tokens' => 8192,
                'temperature' => 0.3,
                'messages' => [
                    ['role' => 'user', 'content' => $prompt],
                ],
            ]);

        if (! $response->successful()) {
            Log::error('Claude API error', [
                'status' => $response->status(),
                'body' => $response->body(),
            ]);
            throw new \RuntimeException('Claude API 호출 실패: '.$response->status());
        }

        $result = $response->json();

        AiTokenHelper::saveClaudeUsage($result, $config->model, $menuName);

        return $result['content'][0]['text'] ?? null;
    }

    /**
     * 1차 프롬프트: 업무 분석
     */
    private function buildAnalysisPrompt(string $interviewText, array $modules): string
    {
        $modulesJson = json_encode($modules, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

        return <<<PROMPT
당신은 SAM(Smart Automation Management) ERP/MES 솔루션의 전문 컨설턴트입니다.

아래는 고객사 직원과의 인터뷰 내용입니다. 이를 분석하여 구조화된 업무 분석 보고서를 JSON으로 작성하세요.

## 인터뷰 내용
{$interviewText}

## SAM 모듈 카탈로그 (분석 기준)
{$modulesJson}

## 출력 형식 (반드시 이 JSON 구조를 따르세요)
{
  "company_analysis": {
    "industry": "업종 분류",
    "scale": "소규모/중소/중견",
    "employee_count_estimate": 0,
    "current_systems": ["현재 사용 중인 시스템"],
    "digitalization_level": "상/중/하"
  },
  "business_domains": [
    {
      "domain": "업무 영역명",
      "current_process": "현재 처리 방식 설명",
      "pain_points": ["문제점 1", "문제점 2"],
      "improvement_needs": ["개선 필요사항"],
      "priority": "필수/높음/보통/낮음",
      "matched_modules": ["모듈코드"]
    }
  ],
  "recommendations": {
    "essential_modules": ["반드시 필요한 모듈 코드"],
    "recommended_modules": ["권장 모듈 코드"],
    "optional_modules": ["선택 모듈 코드"],
    "package_suggestion": "BASIC_PKG 또는 INTEGRATED 또는 individual",
    "reasoning": "패키지 추천 근거"
  }
}

중요: JSON만 출력하세요. 설명이나 마크다운 코드 블록 없이 순수 JSON만 반환하세요.
PROMPT;
    }

    /**
     * 2차 프롬프트: 견적 생성
     */
    private function buildQuotationPrompt(array $analysisResult, array $modules): string
    {
        $analysisJson = json_encode($analysisResult, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        $modulesJson = json_encode($modules, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

        return <<<PROMPT
아래 업무 분석 결과를 바탕으로 SAM 견적서를 생성하세요.

## 업무 분석 결과
{$analysisJson}

## SAM 모듈 카탈로그 (가격 포함)
{$modulesJson}

## 견적 생성 규칙
1. 필수 모듈은 반드시 포함
2. 기본 패키지(BASIC_PKG)에 포함된 모듈(HR, ATTENDANCE, PAYROLL, BOARD)은 개별 추가하지 않음
3. 통합 패키지(INTEGRATED)가 개별 합산보다 저렴하면 패키지 추천
4. is_required가 true인 항목은 반드시 필요한 모듈, false는 선택

## 출력 형식 (반드시 이 JSON 구조를 따르세요)
{
  "quotation_title": "견적서 제목",
  "items": [
    {
      "module_code": "모듈코드",
      "module_name": "모듈명",
      "is_required": true,
      "reason": "이 모듈이 필요한 이유 (인터뷰 내용 기반)",
      "dev_cost": 0,
      "monthly_fee": 0
    }
  ],
  "summary": {
    "total_dev_cost": 0,
    "total_monthly_fee": 0,
    "discount_type": "패키지할인/볼륨할인/없음",
    "discount_rate": 0,
    "final_dev_cost": 0,
    "final_monthly_fee": 0
  },
  "implementation_plan": {
    "estimated_months": 0,
    "phases": [
      {
        "phase": 1,
        "name": "단계명",
        "modules": ["모듈코드"],
        "duration_weeks": 0
      }
    ]
  },
  "analysis_summary": "고객에게 전달할 업무 분석 요약 (2~3문장)"
}

중요: JSON만 출력하세요. 설명이나 마크다운 코드 블록 없이 순수 JSON만 반환하세요.
PROMPT;
    }

    /**
     * AI 응답에서 JSON 추출
     */
    private function parseJsonResponse(?string $response): ?array
    {
        if (! $response) {
            return null;
        }

        // 마크다운 코드 블록 제거
        $cleaned = preg_replace('/^```(?:json)?\s*/m', '', $response);
        $cleaned = preg_replace('/\s*```$/m', '', $cleaned);
        $cleaned = trim($cleaned);

        $decoded = json_decode($cleaned, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::warning('AI JSON 파싱 실패', [
                'error' => json_last_error_msg(),
                'response_preview' => mb_substr($response, 0, 500),
            ]);

            return null;
        }

        return $decoded;
    }

    /**
     * AI 견적 결과를 아이템으로 저장
     */
    private function saveQuotationItems(AiQuotation $quotation, array $quotationResult, array $modules): void
    {
        // 기존 아이템 삭제 (재분석 시)
        $quotation->items()->delete();

        $items = $quotationResult['items'] ?? [];
        $moduleMap = collect($modules)->keyBy('module_code');

        foreach ($items as $index => $item) {
            $moduleCode = $item['module_code'] ?? '';
            $catalogModule = $moduleMap->get($moduleCode);

            // 카탈로그에 있는 모듈이면 DB의 가격 사용 (AI hallucination 방지)
            $devCost = $catalogModule ? $catalogModule['dev_cost'] : ($item['dev_cost'] ?? 0);
            $monthlyFee = $catalogModule ? $catalogModule['monthly_fee'] : ($item['monthly_fee'] ?? 0);

            // DB에서 module_id 조회
            $dbModule = AiQuotationModule::where('module_code', $moduleCode)->first();

            AiQuotationItem::create([
                'ai_quotation_id' => $quotation->id,
                'module_id' => $dbModule?->id,
                'module_code' => $moduleCode,
                'module_name' => $item['module_name'] ?? $moduleCode,
                'is_required' => $item['is_required'] ?? false,
                'reason' => $item['reason'] ?? null,
                'dev_cost' => $devCost,
                'monthly_fee' => $monthlyFee,
                'sort_order' => $index,
            ]);
        }
    }

    // ===================================================
    // 제조 견적 (Manufacture) 전용 메서드
    // ===================================================

    /**
     * 제조 견적 AI 분석 실행
     */
    public function runManufactureAnalysis(AiQuotation $quotation): array
    {
        try {
            $quotation->update(['status' => AiQuotation::STATUS_PROCESSING]);

            $provider = $quotation->ai_provider;
            $config = AiConfig::getActive($provider);

            if (! $config) {
                throw new \RuntimeException("{$provider} API 설정이 없습니다.");
            }

            $productCategory = $quotation->product_category ?? 'SCREEN';
            $priceTables = AiQuotePriceTable::getPriceTablesForPrompt($productCategory);

            // 1차: 요구사항 분석
            $analysisPrompt = $this->buildManufactureAnalysisPrompt(
                $quotation->input_text,
                $productCategory
            );
            $analysisRaw = $this->callAi($config, $provider, $analysisPrompt, 'AI제조견적-분석');

            $analysisResult = $this->parseJsonResponse($analysisRaw);
            if (! $analysisResult) {
                throw new \RuntimeException('AI 요구사항 분석 결과 파싱 실패');
            }

            $quotation->update(['analysis_result' => $analysisResult]);

            // 2차: 견적 산출
            $quotationPrompt = $this->buildManufactureQuotationPrompt(
                $analysisResult,
                $priceTables,
                $productCategory
            );
            $quotationRaw = $this->callAi($config, $provider, $quotationPrompt, 'AI제조견적-산출');

            $quotationResult = $this->parseJsonResponse($quotationRaw);
            if (! $quotationResult) {
                throw new \RuntimeException('AI 견적 산출 결과 파싱 실패');
            }

            // 품목 저장
            $this->saveManufactureItems($quotation, $quotationResult);

            // 합계 계산 + options에 pricing 저장
            $totals = $quotation->items()->selectRaw(
                'SUM(total_price) as subtotal'
            )->first();

            $subtotal = (int) ($totals->subtotal ?? 0);
            $pricing = $quotationResult['pricing'] ?? [];
            $discountRate = (float) ($pricing['discount_rate'] ?? 0);
            $discountAmount = (int) round($subtotal * $discountRate / 100);
            $afterDiscount = $subtotal - $discountAmount;
            $vatAmount = (int) round($afterDiscount * 0.1);
            $finalAmount = $afterDiscount + $vatAmount;

            // 고객 정보 업데이트 (AI가 추출한 정보로 보강)
            $clientFromAi = $analysisResult['client'] ?? [];
            $existingOptions = $quotation->options ?? [];
            $existingClient = $existingOptions['client'] ?? [];
            $mergedClient = array_filter(array_merge($clientFromAi, $existingClient));

            $existingOptions['client'] = $mergedClient;
            $existingOptions['project'] = $analysisResult['project'] ?? [];
            $existingOptions['pricing'] = [
                'subtotal' => $subtotal,
                'material_cost' => (int) ($pricing['material_cost'] ?? 0),
                'labor_cost' => (int) ($pricing['labor_cost'] ?? 0),
                'install_cost' => (int) ($pricing['install_cost'] ?? 0),
                'discount_rate' => $discountRate,
                'discount_amount' => $discountAmount,
                'vat_amount' => $vatAmount,
                'final_amount' => $finalAmount,
            ];
            $existingOptions['terms'] = $quotationResult['terms'] ?? [
                'valid_until' => now()->addDays(30)->format('Y-m-d'),
                'payment' => '계약 시 50%, 설치 완료 후 50%',
                'delivery' => '계약 후 4주 이내',
            ];

            $quotation->update([
                'quotation_result' => $quotationResult,
                'ai_model' => $config->model,
                'total_dev_cost' => $finalAmount,
                'total_monthly_fee' => 0,
                'options' => $existingOptions,
                'status' => AiQuotation::STATUS_COMPLETED,
            ]);

            return [
                'ok' => true,
                'quotation' => $quotation->fresh(['items', 'creator:id,name']),
            ];
        } catch (\Exception $e) {
            Log::error('AI 제조 견적 분석 실패', [
                'quotation_id' => $quotation->id,
                'error' => $e->getMessage(),
            ]);

            $quotation->update(['status' => AiQuotation::STATUS_FAILED]);

            return [
                'ok' => false,
                'error' => $e->getMessage(),
                'quotation' => $quotation->fresh(),
            ];
        }
    }

    /**
     * 견적번호 자동 생성
     */
    public function generateQuoteNumber(?string $productCategory): string
    {
        $prefix = match (strtoupper($productCategory ?? 'SC')) {
            'SCREEN' => 'SC',
            'STEEL' => 'ST',
            default => 'SC',
        };

        $dateStr = now()->format('ymd');
        $baseNumber = "AQ-{$prefix}-{$dateStr}";

        $count = AiQuotation::where('quote_number', 'like', "{$baseNumber}-%")->count();
        $seq = str_pad($count + 1, 2, '0', STR_PAD_LEFT);

        return "{$baseNumber}-{$seq}";
    }

    /**
     * 제조 견적 품목 저장
     */
    private function saveManufactureItems(AiQuotation $quotation, array $quotationResult): void
    {
        $quotation->items()->delete();

        $items = $quotationResult['items'] ?? [];

        foreach ($items as $index => $item) {
            $quantity = (float) ($item['quantity'] ?? 1);
            $unitPrice = (float) ($item['unit_price'] ?? 0);
            $totalPrice = (float) ($item['total_price'] ?? ($quantity * $unitPrice));

            AiQuotationItem::create([
                'ai_quotation_id' => $quotation->id,
                'module_code' => $item['item_code'] ?? '',
                'module_name' => $item['item_name'] ?? '',
                'specification' => $item['specification'] ?? null,
                'unit' => $item['unit'] ?? 'SET',
                'quantity' => $quantity,
                'unit_price' => $unitPrice,
                'total_price' => $totalPrice,
                'item_category' => $item['item_category'] ?? 'material',
                'floor_code' => $item['floor_code'] ?? null,
                'reason' => $item['description'] ?? null,
                'sort_order' => $index,
            ]);
        }
    }

    /**
     * 견적 편집 저장
     */
    public function updateQuotation(int $id, array $data): array
    {
        $quotation = $this->getById($id);

        if (! $quotation) {
            return ['ok' => false, 'error' => '견적을 찾을 수 없습니다.'];
        }

        DB::beginTransaction();
        try {
            // options 업데이트
            $options = $quotation->options ?? [];

            if (isset($data['client'])) {
                $options['client'] = $data['client'];
            }
            if (isset($data['project'])) {
                $options['project'] = $data['project'];
            }
            if (isset($data['terms'])) {
                $options['terms'] = $data['terms'];
            }

            // 품목 업데이트
            if (isset($data['items'])) {
                $quotation->items()->delete();
                $subtotal = 0;
                $materialCost = 0;
                $laborCost = 0;
                $installCost = 0;

                foreach ($data['items'] as $index => $item) {
                    $qty = (float) ($item['quantity'] ?? 1);
                    $price = (float) ($item['unit_price'] ?? 0);
                    $total = round($qty * $price, 2);
                    $subtotal += $total;

                    $cat = $item['item_category'] ?? 'material';
                    if ($cat === 'material') {
                        $materialCost += $total;
                    } elseif ($cat === 'labor') {
                        $laborCost += $total;
                    } elseif ($cat === 'install') {
                        $installCost += $total;
                    }

                    AiQuotationItem::create([
                        'ai_quotation_id' => $quotation->id,
                        'module_code' => $item['item_code'] ?? '',
                        'module_name' => $item['item_name'] ?? '',
                        'specification' => $item['specification'] ?? null,
                        'unit' => $item['unit'] ?? 'SET',
                        'quantity' => $qty,
                        'unit_price' => $price,
                        'total_price' => $total,
                        'item_category' => $cat,
                        'floor_code' => $item['floor_code'] ?? null,
                        'reason' => $item['description'] ?? null,
                        'sort_order' => $index,
                    ]);
                }

                // 가격 재계산
                $discountRate = (float) ($data['discount_rate'] ?? $options['pricing']['discount_rate'] ?? 0);
                $discountAmount = (int) round($subtotal * $discountRate / 100);
                $afterDiscount = $subtotal - $discountAmount;
                $vatAmount = (int) round($afterDiscount * 0.1);
                $finalAmount = $afterDiscount + $vatAmount;

                $options['pricing'] = [
                    'subtotal' => (int) $subtotal,
                    'material_cost' => (int) $materialCost,
                    'labor_cost' => (int) $laborCost,
                    'install_cost' => (int) $installCost,
                    'discount_rate' => $discountRate,
                    'discount_amount' => $discountAmount,
                    'vat_amount' => $vatAmount,
                    'final_amount' => $finalAmount,
                ];

                $quotation->update([
                    'total_dev_cost' => $finalAmount,
                    'total_monthly_fee' => 0,
                ]);
            }

            $quotation->update(['options' => $options]);

            DB::commit();

            return [
                'ok' => true,
                'quotation' => $quotation->fresh(['items', 'creator:id,name']),
            ];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('견적 편집 저장 실패', [
                'quotation_id' => $id,
                'error' => $e->getMessage(),
            ]);

            return ['ok' => false, 'error' => $e->getMessage()];
        }
    }

    /**
     * 금액을 한글로 변환
     */
    public static function numberToKorean(int $number): string
    {
        if ($number === 0) {
            return '영';
        }

        $units = ['', '만', '억', '조'];
        $digits = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구'];
        $subUnits = ['', '십', '백', '천'];

        $result = '';
        $unitIndex = 0;

        while ($number > 0) {
            $chunk = $number % 10000;
            if ($chunk > 0) {
                $chunkStr = '';
                $subIndex = 0;
                $temp = $chunk;
                while ($temp > 0) {
                    $digit = $temp % 10;
                    if ($digit > 0) {
                        $prefix = ($digit === 1 && $subIndex > 0) ? '' : $digits[$digit];
                        $chunkStr = $prefix.$subUnits[$subIndex].$chunkStr;
                    }
                    $temp = (int) ($temp / 10);
                    $subIndex++;
                }
                $result = $chunkStr.$units[$unitIndex].$result;
            }
            $number = (int) ($number / 10000);
            $unitIndex++;
        }

        return $result;
    }

    // ===================================================
    // 제조 견적 AI 프롬프트
    // ===================================================

    /**
     * 제조 견적용 1단계: 요구사항 분석
     */
    private function buildManufactureAnalysisPrompt(string $interviewText, string $productCategory): string
    {
        $categoryLabel = $productCategory === 'STEEL' ? '철재(방화문/방화셔터)' : '방화스크린';

        return <<<PROMPT
당신은 {$categoryLabel} 제조업체의 영업 전문가입니다.
고객 인터뷰/상담 내용을 분석하여 견적에 필요한 정보를 구조화된 JSON으로 추출하세요.

## 상담 내용
{$interviewText}

## 추출 대상
1. 고객 정보 (회사명, 담당자, 연락처, 이메일, 주소)
2. 프로젝트 정보 (현장명, 위치, 건물유형, 용도)
3. 위치별 제품 사양 (층/부호, 제품유형, 개구부 크기 W×H mm, 수량, 가이드레일 유형, 모터, 특이사항)
4. 설치 조건 (접근성, 전원, 층고 등)
5. 고객 특이 요청사항

## 출력 형식 (반드시 이 JSON 구조를 따르세요)
{
  "client": {
    "company": "회사명 또는 null",
    "contact": "담당자명 또는 null",
    "phone": "연락처 또는 null",
    "email": "이메일 또는 null",
    "address": "주소 또는 null"
  },
  "project": {
    "name": "현장명/프로젝트명",
    "location": "현장 위치",
    "building_type": "건물유형 (오피스/상가/공장 등)",
    "purpose": "용도"
  },
  "product_specs": [
    {
      "floor_code": "위치 코드 (예: B1-A01)",
      "floor_name": "위치 설명 (예: 지하1층 A구역)",
      "product_type": "SCREEN 또는 STEEL",
      "width_mm": 3000,
      "height_mm": 2500,
      "quantity": 1,
      "guide_rail": "벽부형/노출형/매립형",
      "motor": "단상/삼상",
      "note": "특이사항 또는 null"
    }
  ],
  "install_conditions": {
    "accessibility": "양호/보통/불량",
    "power_source": "단상/삼상",
    "ceiling_height": "층고 정보 또는 null",
    "special_requirements": "특수 요구사항 또는 null"
  },
  "customer_requests": "고객 특이 요청사항 텍스트 또는 null"
}

중요: JSON만 출력하세요. 설명이나 마크다운 코드 블록 없이 순수 JSON만 반환하세요.
인터뷰에서 명시되지 않은 정보는 null로 설정하세요.
PROMPT;
    }

    /**
     * 제조 견적용 2단계: 견적 산출
     */
    private function buildManufactureQuotationPrompt(array $analysisResult, array $priceTables, string $productCategory): string
    {
        $analysisJson = json_encode($analysisResult, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        $priceJson = json_encode($priceTables, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        $categoryLabel = $productCategory === 'STEEL' ? '철재' : '방화스크린';

        return <<<PROMPT
아래 분석 결과를 바탕으로 {$categoryLabel} 제조 견적을 산출하세요.

## 분석 결과
{$analysisJson}

## 단가표
{$priceJson}

## 산출 규칙 (방화스크린 기준)
1. 유효 면적 계산: M = (W + 140) × (H + 350) / 1,000,000 (단위: ㎡)
   - W: 개구부 폭(mm), H: 개구부 높이(mm)
   - 140, 350은 가이드레일/하부 여유분
2. 단가 적용: 면적 구간별 단가표 참조 (단가표가 없으면 ㎡당 350,000원 기본 적용)
3. 재료비 = 면적 × 단가 × 수량
4. 노무비 = 재료비 × 노무비율 (단가표 labor_rate, 기본 15%)
5. 설치비 = 재료비 × 설치비율 (단가표 install_rate, 기본 10%)
6. 가이드레일, 케이스, 모터 등 부대재료는 별도 행으로 산출

## 출력 형식 (반드시 이 JSON 구조를 따르세요)
{
  "items": [
    {
      "item_code": "SCR-001",
      "item_name": "방화스크린 본체",
      "specification": "3140×2850",
      "unit": "SET",
      "quantity": 1,
      "unit_price": 350000,
      "total_price": 350000,
      "item_category": "material",
      "floor_code": "B1-A01",
      "description": "지하1층 A구역 방화스크린"
    },
    {
      "item_code": "LBR-001",
      "item_name": "설치 노무비",
      "specification": "",
      "unit": "식",
      "quantity": 1,
      "unit_price": 52500,
      "total_price": 52500,
      "item_category": "labor",
      "floor_code": "",
      "description": "스크린 설치 인건비"
    }
  ],
  "pricing": {
    "material_cost": 0,
    "labor_cost": 0,
    "install_cost": 0,
    "discount_rate": 0,
    "note": "할인 근거 또는 null"
  },
  "terms": {
    "valid_until": "유효기간 날짜 (YYYY-MM-DD)",
    "payment": "결제 조건",
    "delivery": "납기 조건"
  }
}

중요:
- JSON만 출력하세요. 설명이나 마크다운 코드 블록 없이 순수 JSON만 반환하세요.
- item_category는 반드시 "material", "labor", "install" 중 하나여야 합니다.
- 모든 금액은 원 단위 정수로 작성하세요.
- 위치별로 재료비 품목을 각각 작성하고, 노무비와 설치비는 전체 합산 1행으로 작성하세요.
PROMPT;
    }

    /**
     * 대시보드 통계
     */
    public function getDashboardStats(): array
    {
        $stats = AiQuotation::query()
            ->selectRaw("
                COUNT(*) as total,
                SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing,
                SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
                SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending
            ")
            ->first();

        $recent = AiQuotation::with('creator:id,name')
            ->orderBy('created_at', 'desc')
            ->limit(5)
            ->get();

        return [
            'stats' => [
                'total' => (int) $stats->total,
                'completed' => (int) $stats->completed,
                'processing' => (int) $stats->processing,
                'failed' => (int) $stats->failed,
                'pending' => (int) $stats->pending,
            ],
            'recent' => $recent,
        ];
    }
}
