<?php

namespace App\Services\Quote;

use App\Models\Quote\Quote;
use App\Services\Service;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * 견적 문서 서비스
 *
 * 견적서 PDF 생성 및 발송(이메일, 카카오톡)을 담당합니다.
 */
class QuoteDocumentService extends Service
{
    /**
     * 발송 채널 상수
     */
    public const CHANNEL_EMAIL = 'email';

    public const CHANNEL_KAKAO = 'kakao';

    public const CHANNEL_FAX = 'fax';

    /**
     * 문서 유형 상수
     */
    public const DOC_TYPE_QUOTE = 'quote';

    public const DOC_TYPE_ORDER = 'order';

    public const DOC_TYPE_INVOICE = 'invoice';

    /**
     * 발송 상태 상수
     */
    public const STATUS_PENDING = 'pending';

    public const STATUS_SENT = 'sent';

    public const STATUS_FAILED = 'failed';

    public const STATUS_DELIVERED = 'delivered';

    public const STATUS_READ = 'read';

    /**
     * 견적서 PDF 생성
     */
    public function generatePdf(int $quoteId): array
    {
        $tenantId = $this->tenantId();

        $quote = Quote::with(['items', 'client'])
            ->where('tenant_id', $tenantId)
            ->find($quoteId);

        if (! $quote) {
            throw new NotFoundHttpException(__('error.quote_not_found'));
        }

        // PDF 생성 데이터 준비
        $data = $this->preparePdfData($quote);

        // TODO: 실제 PDF 생성 로직 구현 (barryvdh/laravel-dompdf 등 사용)
        // 현재는 기본 구조만 제공
        $filename = $this->generateFilename($quote);
        $path = "quotes/{$tenantId}/{$filename}";

        // 임시: PDF 생성 시뮬레이션
        // Storage::disk('local')->put($path, $this->generatePdfContent($data));

        return [
            'quote_id' => $quoteId,
            'quote_number' => $quote->quote_number,
            'filename' => $filename,
            'path' => $path,
            'generated_at' => now()->toDateTimeString(),
            'data' => $data, // 개발 단계에서 확인용
        ];
    }

    /**
     * 견적서 이메일 발송
     */
    public function sendEmail(int $quoteId, array $options = []): array
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $quote = Quote::with(['items', 'client'])
            ->where('tenant_id', $tenantId)
            ->find($quoteId);

        if (! $quote) {
            throw new NotFoundHttpException(__('error.quote_not_found'));
        }

        // 수신자 정보
        $recipientEmail = $options['email'] ?? $quote->client?->email ?? null;
        $recipientName = $options['name'] ?? $quote->client_name ?? $quote->client?->name ?? null;

        if (! $recipientEmail) {
            throw new BadRequestHttpException(__('error.quote_email_not_found'));
        }

        // 이메일 옵션
        $subject = $options['subject'] ?? $this->getDefaultEmailSubject($quote);
        $message = $options['message'] ?? $this->getDefaultEmailMessage($quote);
        $cc = $options['cc'] ?? [];
        $attachPdf = $options['attach_pdf'] ?? true;

        // PDF 생성 (첨부 시)
        $pdfInfo = null;
        if ($attachPdf) {
            $pdfInfo = $this->generatePdf($quoteId);
        }

        // TODO: 실제 이메일 발송 로직 구현 (Laravel Mail 사용)
        // Mail::to($recipientEmail)->send(new QuoteMail($quote, $pdfInfo));

        // 발송 이력 기록
        $sendLog = $this->createSendLog($quote, [
            'channel' => self::CHANNEL_EMAIL,
            'recipient_email' => $recipientEmail,
            'recipient_name' => $recipientName,
            'subject' => $subject,
            'message' => $message,
            'cc' => $cc,
            'pdf_path' => $pdfInfo['path'] ?? null,
            'sent_by' => $userId,
        ]);

        // 견적 상태 업데이트 (draft → sent)
        if ($quote->status === Quote::STATUS_DRAFT) {
            $quote->update([
                'status' => Quote::STATUS_SENT,
                'updated_by' => $userId,
            ]);
        }

        return [
            'success' => true,
            'message' => __('message.quote_email_sent'),
            'send_log' => $sendLog,
            'quote_status' => $quote->fresh()->status,
        ];
    }

    /**
     * 견적서 카카오톡 발송
     */
    public function sendKakao(int $quoteId, array $options = []): array
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        $quote = Quote::with(['items', 'client'])
            ->where('tenant_id', $tenantId)
            ->find($quoteId);

        if (! $quote) {
            throw new NotFoundHttpException(__('error.quote_not_found'));
        }

        // 수신자 정보
        $recipientPhone = $options['phone'] ?? $quote->contact ?? $quote->client?->phone ?? null;
        $recipientName = $options['name'] ?? $quote->client_name ?? $quote->client?->name ?? null;

        if (! $recipientPhone) {
            throw new BadRequestHttpException(__('error.quote_phone_not_found'));
        }

        // 알림톡 템플릿 데이터
        $templateCode = $options['template_code'] ?? 'QUOTE_SEND';
        $templateData = $this->prepareKakaoTemplateData($quote, $options);

        // TODO: 실제 카카오 알림톡 발송 로직 구현
        // 외부 API 연동 필요 (NHN Cloud, Solapi 등)

        // 발송 이력 기록
        $sendLog = $this->createSendLog($quote, [
            'channel' => self::CHANNEL_KAKAO,
            'recipient_phone' => $recipientPhone,
            'recipient_name' => $recipientName,
            'template_code' => $templateCode,
            'template_data' => $templateData,
            'sent_by' => $userId,
        ]);

        // 견적 상태 업데이트 (draft → sent)
        if ($quote->status === Quote::STATUS_DRAFT) {
            $quote->update([
                'status' => Quote::STATUS_SENT,
                'updated_by' => $userId,
            ]);
        }

        return [
            'success' => true,
            'message' => __('message.quote_kakao_sent'),
            'send_log' => $sendLog,
            'quote_status' => $quote->fresh()->status,
        ];
    }

    /**
     * 발송 이력 조회
     */
    public function getSendHistory(int $quoteId): array
    {
        $tenantId = $this->tenantId();

        $quote = Quote::where('tenant_id', $tenantId)->find($quoteId);

        if (! $quote) {
            throw new NotFoundHttpException(__('error.quote_not_found'));
        }

        // TODO: 발송 이력 테이블 조회
        // QuoteSendLog::where('quote_id', $quoteId)->orderByDesc('created_at')->get();

        return [
            'quote_id' => $quoteId,
            'quote_number' => $quote->quote_number,
            'history' => [], // 발송 이력 배열
        ];
    }

    /**
     * PDF 데이터 준비
     */
    private function preparePdfData(Quote $quote): array
    {
        // 회사 정보 (테넌트 설정에서)
        $companyInfo = [
            'name' => config('app.company_name', 'KD 건축자재'),
            'address' => config('app.company_address', ''),
            'phone' => config('app.company_phone', ''),
            'email' => config('app.company_email', ''),
            'registration_number' => config('app.company_registration_number', ''),
        ];

        // 거래처 정보
        $clientInfo = [
            'name' => $quote->client_name ?? $quote->client?->name ?? '',
            'manager' => $quote->manager ?? '',
            'contact' => $quote->contact ?? '',
            'address' => $quote->client?->address ?? '',
        ];

        // 견적 기본 정보
        $quoteInfo = [
            'quote_number' => $quote->quote_number,
            'registration_date' => $quote->registration_date?->format('Y-m-d'),
            'completion_date' => $quote->completion_date?->format('Y-m-d'),
            'product_category' => $quote->product_category,
            'product_name' => $quote->product_name,
            'site_name' => $quote->site_name,
            'author' => $quote->author,
        ];

        // 규격 정보
        $specInfo = [
            'open_size_width' => $quote->open_size_width,
            'open_size_height' => $quote->open_size_height,
            'quantity' => $quote->quantity,
            'unit_symbol' => $quote->unit_symbol,
            'floors' => $quote->floors,
        ];

        // 품목 목록
        $items = $quote->items->map(fn ($item) => [
            'item_code' => $item->item_code,
            'item_name' => $item->item_name,
            'specification' => $item->specification,
            'unit' => $item->unit,
            'quantity' => $item->calculated_quantity,
            'unit_price' => $item->unit_price,
            'total_price' => $item->total_price,
            'note' => $item->note,
        ])->toArray();

        // 금액 정보
        $amounts = [
            'material_cost' => $quote->material_cost,
            'labor_cost' => $quote->labor_cost,
            'install_cost' => $quote->install_cost,
            'subtotal' => $quote->subtotal,
            'discount_rate' => $quote->discount_rate,
            'discount_amount' => $quote->discount_amount,
            'total_amount' => $quote->total_amount,
        ];

        return [
            'company' => $companyInfo,
            'client' => $clientInfo,
            'quote' => $quoteInfo,
            'spec' => $specInfo,
            'items' => $items,
            'amounts' => $amounts,
            'remarks' => $quote->remarks,
            'notes' => $quote->notes,
        ];
    }

    /**
     * 파일명 생성
     */
    private function generateFilename(Quote $quote): string
    {
        $date = now()->format('Ymd');

        return "quote_{$quote->quote_number}_{$date}.pdf";
    }

    /**
     * 기본 이메일 제목
     */
    private function getDefaultEmailSubject(Quote $quote): string
    {
        return "[견적서] {$quote->quote_number} - {$quote->product_name}";
    }

    /**
     * 기본 이메일 본문
     */
    private function getDefaultEmailMessage(Quote $quote): string
    {
        $clientName = $quote->client_name ?? '고객';

        return <<<MESSAGE
안녕하세요, {$clientName} 담당자님.

요청하신 견적서를 송부드립니다.

[견적 정보]
- 견적번호: {$quote->quote_number}
- 제품명: {$quote->product_name}
- 현장명: {$quote->site_name}
- 견적금액: ₩ {$quote->total_amount}

첨부된 견적서를 확인해 주시기 바랍니다.
문의사항이 있으시면 언제든 연락 주세요.

감사합니다.
MESSAGE;
    }

    /**
     * 카카오 알림톡 템플릿 데이터 준비
     */
    private function prepareKakaoTemplateData(Quote $quote, array $options = []): array
    {
        return [
            'quote_number' => $quote->quote_number,
            'client_name' => $quote->client_name ?? '',
            'product_name' => $quote->product_name ?? '',
            'site_name' => $quote->site_name ?? '',
            'total_amount' => number_format((float) $quote->total_amount),
            'registration_date' => $quote->registration_date?->format('Y-m-d'),
            'view_url' => $options['view_url'] ?? '', // 견적서 조회 URL
        ];
    }

    /**
     * 발송 이력 생성
     */
    private function createSendLog(Quote $quote, array $data): array
    {
        // TODO: QuoteSendLog 모델 생성 후 실제 DB 저장 구현
        // QuoteSendLog::create([
        //     'tenant_id' => $quote->tenant_id,
        //     'quote_id' => $quote->id,
        //     'channel' => $data['channel'],
        //     ...
        // ]);

        return array_merge([
            'quote_id' => $quote->id,
            'quote_number' => $quote->quote_number,
            'status' => self::STATUS_PENDING,
            'sent_at' => now()->toDateTimeString(),
        ], $data);
    }
}
