<?php

namespace App\Http\Controllers\Sales;

use App\Http\Controllers\Controller;
use App\Models\Sales\SalesConsultation;
use App\Models\Sales\TenantProspect;
use App\Models\Tenants\Tenant;
use App\Services\GoogleCloudStorageService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

/**
 * 상담 기록 관리 컨트롤러
 *
 * 테넌트별 상담 기록(텍스트, 음성, 파일)을 관리합니다.
 * 데이터는 sales_consultations 테이블에 저장됩니다.
 */
class ConsultationController extends Controller
{
    /**
     * 상담 기록 목록 (HTMX 부분 뷰)
     */
    public function index(int $tenantId, Request $request): View
    {
        $tenant = Tenant::findOrFail($tenantId);
        $scenarioType = $request->input('scenario_type', 'sales');
        $stepId = $request->input('step_id');

        // DB에서 상담 기록 조회
        $consultations = SalesConsultation::getByTenantAndType($tenantId, $scenarioType, $stepId);

        return view('sales.modals.consultation-log', [
            'tenant' => $tenant,
            'consultations' => $consultations,
            'scenarioType' => $scenarioType,
            'stepId' => $stepId,
        ]);
    }

    /**
     * 텍스트 상담 기록 저장
     */
    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'tenant_id' => 'required|integer|exists:tenants,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'content' => 'required|string|max:5000',
        ]);

        $consultation = SalesConsultation::createText(
            $request->input('tenant_id'),
            $request->input('scenario_type'),
            $request->input('step_id'),
            $request->input('content')
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'content' => $consultation->content,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
            ],
        ]);
    }

    /**
     * 상담 기록 삭제
     */
    public function destroy(int $consultationId, Request $request): JsonResponse
    {
        $consultation = SalesConsultation::findOrFail($consultationId);

        // 파일이 있으면 함께 삭제
        $consultation->deleteWithFile();

        return response()->json([
            'success' => true,
        ]);
    }

    /**
     * 음성 파일 업로드
     *
     * 10MB 이상 파일은 Google Cloud Storage에 업로드하여 본사 연구용으로 보관합니다.
     */
    public function uploadAudio(Request $request, GoogleCloudStorageService $gcs): JsonResponse
    {
        $request->validate([
            'tenant_id' => 'required|integer|exists:tenants,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'audio' => 'required|file|mimes:webm,mp3,wav,ogg|max:51200', // 50MB
            'transcript' => 'nullable|string|max:10000',
            'duration' => 'nullable|integer',
        ]);

        $tenantId = $request->input('tenant_id');
        $scenarioType = $request->input('scenario_type');
        $stepId = $request->input('step_id');
        $transcript = $request->input('transcript');
        $duration = $request->input('duration');

        // 파일 저장
        $file = $request->file('audio');
        $fileName = 'audio_'.now()->format('Ymd_His').'_'.uniqid().'.'.$file->getClientOriginalExtension();
        $localPath = $file->storeAs("tenant/consultations/{$tenantId}", $fileName, 'local');
        $fileSize = $file->getSize();

        // 10MB 이상 파일은 GCS에도 업로드 (본사 연구용)
        $gcsUri = null;
        $maxLocalSize = 10 * 1024 * 1024; // 10MB

        if ($fileSize > $maxLocalSize && $gcs->isAvailable()) {
            $gcsObjectName = "consultations/{$tenantId}/{$scenarioType}/{$fileName}";
            $localFullPath = Storage::disk('local')->path($localPath);
            $gcsUri = $gcs->upload($localFullPath, $gcsObjectName);
        }

        // DB에 저장
        $consultation = SalesConsultation::createAudio(
            $tenantId,
            $scenarioType,
            $stepId,
            $localPath,
            $fileName,
            $fileSize,
            $transcript,
            $duration,
            $gcsUri
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'file_name' => $consultation->file_name,
                'transcript' => $consultation->transcript,
                'duration' => $consultation->duration,
                'formatted_duration' => $consultation->formatted_duration,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
                'has_gcs' => ! empty($gcsUri),
            ],
        ]);
    }

    /**
     * 첨부파일 업로드
     */
    public function uploadFile(Request $request): JsonResponse
    {
        $request->validate([
            'tenant_id' => 'required|integer|exists:tenants,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'file' => 'required|file|max:20480', // 20MB
        ]);

        $tenantId = $request->input('tenant_id');
        $scenarioType = $request->input('scenario_type');
        $stepId = $request->input('step_id');

        // 파일 저장
        $file = $request->file('file');
        $originalName = $file->getClientOriginalName();
        $fileName = now()->format('Ymd_His').'_'.uniqid().'_'.$originalName;
        $path = $file->storeAs("tenant/attachments/{$tenantId}", $fileName, 'local');

        // DB에 저장
        $consultation = SalesConsultation::createFile(
            $tenantId,
            $scenarioType,
            $stepId,
            $path,
            $originalName,
            $file->getSize(),
            $file->getMimeType()
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'file_name' => $consultation->file_name,
                'file_size' => $consultation->file_size,
                'formatted_file_size' => $consultation->formatted_file_size,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
            ],
        ]);
    }

    /**
     * 파일 삭제
     */
    public function deleteFile(int $fileId, Request $request): JsonResponse
    {
        return $this->destroy($fileId, $request);
    }

    /**
     * 오디오 파일 다운로드
     */
    public function downloadAudio(int $consultationId, GoogleCloudStorageService $gcs): BinaryFileResponse|RedirectResponse
    {
        $consultation = SalesConsultation::findOrFail($consultationId);

        if ($consultation->consultation_type !== 'audio') {
            abort(400, '오디오 파일이 아닙니다.');
        }

        // GCS에 저장된 경우 서명된 URL로 리다이렉트
        if ($consultation->gcs_uri) {
            $objectName = str_replace('gs://'.$gcs->getBucketName().'/', '', $consultation->gcs_uri);
            $signedUrl = $gcs->getSignedUrl($objectName, 60);

            if ($signedUrl) {
                return redirect()->away($signedUrl);
            }
        }

        // 로컬 파일 다운로드
        $localPath = Storage::disk('local')->path($consultation->file_path);

        if (! file_exists($localPath)) {
            abort(404, '파일을 찾을 수 없습니다.');
        }

        $extension = pathinfo($consultation->file_name, PATHINFO_EXTENSION) ?: 'webm';
        $mimeTypes = [
            'webm' => 'audio/webm',
            'wav' => 'audio/wav',
            'mp3' => 'audio/mpeg',
            'ogg' => 'audio/ogg',
            'm4a' => 'audio/mp4',
        ];
        $contentType = $mimeTypes[$extension] ?? 'audio/webm';

        $downloadFileName = '상담녹음_'.$consultation->created_at->format('Ymd_His').'.'.$extension;

        return response()->download($localPath, $downloadFileName, [
            'Content-Type' => $contentType,
        ]);
    }

    /**
     * 첨부파일 다운로드
     */
    public function downloadFile(int $consultationId): BinaryFileResponse
    {
        $consultation = SalesConsultation::findOrFail($consultationId);

        if ($consultation->consultation_type !== 'file') {
            abort(400, '첨부파일이 아닙니다.');
        }

        $localPath = Storage::disk('local')->path($consultation->file_path);

        if (! file_exists($localPath)) {
            abort(404, '파일을 찾을 수 없습니다.');
        }

        return response()->download($localPath, $consultation->file_name);
    }

    // ========================================
    // Prospect(가망고객) 관련 메서드
    // ========================================

    /**
     * 가망고객 상담 기록 목록 (HTMX 부분 뷰)
     */
    public function prospectIndex(int $prospectId, Request $request): View
    {
        $prospect = TenantProspect::findOrFail($prospectId);
        $scenarioType = $request->input('scenario_type', 'sales');
        $stepId = $request->input('step_id');

        $consultations = SalesConsultation::getByProspectAndType($prospectId, $scenarioType, $stepId);

        return view('sales.modals.consultation-log', [
            'prospect' => $prospect,
            'isProspect' => true,
            'consultations' => $consultations,
            'scenarioType' => $scenarioType,
            'stepId' => $stepId,
        ]);
    }

    /**
     * 가망고객 텍스트 상담 기록 저장
     */
    public function prospectStore(Request $request): JsonResponse
    {
        $request->validate([
            'prospect_id' => 'required|integer|exists:tenant_prospects,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'content' => 'required|string|max:5000',
        ]);

        $consultation = SalesConsultation::createTextByProspect(
            $request->input('prospect_id'),
            $request->input('scenario_type'),
            $request->input('step_id'),
            $request->input('content')
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'content' => $consultation->content,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
            ],
        ]);
    }

    /**
     * 가망고객 음성 파일 업로드
     */
    public function prospectUploadAudio(Request $request, GoogleCloudStorageService $gcs): JsonResponse
    {
        $request->validate([
            'prospect_id' => 'required|integer|exists:tenant_prospects,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'audio' => 'required|file|mimes:webm,mp3,wav,ogg|max:51200',
            'transcript' => 'nullable|string|max:10000',
            'duration' => 'nullable|integer',
        ]);

        $prospectId = $request->input('prospect_id');
        $scenarioType = $request->input('scenario_type');
        $stepId = $request->input('step_id');
        $transcript = $request->input('transcript');
        $duration = $request->input('duration');

        $file = $request->file('audio');
        $fileName = 'audio_'.now()->format('Ymd_His').'_'.uniqid().'.'.$file->getClientOriginalExtension();
        $localPath = $file->storeAs("prospect/consultations/{$prospectId}", $fileName, 'local');
        $fileSize = $file->getSize();

        $gcsUri = null;
        $maxLocalSize = 10 * 1024 * 1024;

        if ($fileSize > $maxLocalSize && $gcs->isAvailable()) {
            $gcsObjectName = "consultations/prospect/{$prospectId}/{$scenarioType}/{$fileName}";
            $localFullPath = Storage::disk('local')->path($localPath);
            $gcsUri = $gcs->upload($localFullPath, $gcsObjectName);
        }

        $consultation = SalesConsultation::createAudioByProspect(
            $prospectId,
            $scenarioType,
            $stepId,
            $localPath,
            $fileName,
            $fileSize,
            $transcript,
            $duration,
            $gcsUri
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'file_name' => $consultation->file_name,
                'transcript' => $consultation->transcript,
                'duration' => $consultation->duration,
                'formatted_duration' => $consultation->formatted_duration,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
                'has_gcs' => ! empty($gcsUri),
            ],
        ]);
    }

    /**
     * 가망고객 첨부파일 업로드
     */
    public function prospectUploadFile(Request $request): JsonResponse
    {
        $request->validate([
            'prospect_id' => 'required|integer|exists:tenant_prospects,id',
            'scenario_type' => 'required|in:sales,manager',
            'step_id' => 'nullable|integer',
            'file' => 'required|file|max:20480',
        ]);

        $prospectId = $request->input('prospect_id');
        $scenarioType = $request->input('scenario_type');
        $stepId = $request->input('step_id');

        $file = $request->file('file');
        $originalName = $file->getClientOriginalName();
        $fileName = now()->format('Ymd_His').'_'.uniqid().'_'.$originalName;
        $path = $file->storeAs("prospect/attachments/{$prospectId}", $fileName, 'local');

        $consultation = SalesConsultation::createFileByProspect(
            $prospectId,
            $scenarioType,
            $stepId,
            $path,
            $originalName,
            $file->getSize(),
            $file->getMimeType()
        );

        $consultation->load('creator');

        return response()->json([
            'success' => true,
            'consultation' => [
                'id' => $consultation->id,
                'type' => $consultation->consultation_type,
                'file_name' => $consultation->file_name,
                'file_size' => $consultation->file_size,
                'formatted_file_size' => $consultation->formatted_file_size,
                'created_by_name' => $consultation->creator->name,
                'created_at' => $consultation->created_at->format('Y-m-d H:i'),
            ],
        ]);
    }
}
