<?php

namespace App\Http\Controllers\Video;

use App\Http\Controllers\Controller;
use App\Jobs\TutorialVideoJob;
use App\Models\TutorialVideo;
use App\Services\GoogleCloudStorageService;
use App\Services\Video\ScreenAnalysisService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class TutorialVideoController extends Controller
{
    public function __construct(
        private readonly GoogleCloudStorageService $gcsService,
        private readonly ScreenAnalysisService $screenAnalysisService
    ) {}

    /**
     * 메인 페이지
     */
    public function index(Request $request): View|Response
    {
        if ($request->header('HX-Request')) {
            return response('', 200)->header('HX-Redirect', route('video.tutorial.index'));
        }

        return view('video.tutorial.index');
    }

    /**
     * 스크린샷 업로드 (임시 저장)
     */
    public function upload(Request $request): JsonResponse
    {
        $request->validate([
            'screenshots' => 'required|array|min:1|max:10',
            'screenshots.*' => 'required|image|max:10240', // 최대 10MB
        ]);

        $uploadDir = storage_path('app/tutorial_uploads/'.auth()->id().'/'.time());
        if (! is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        $paths = [];
        foreach ($request->file('screenshots') as $i => $file) {
            $filename = sprintf('screenshot_%02d.%s', $i + 1, $file->getClientOriginalExtension());
            $file->move($uploadDir, $filename);
            $paths[] = $uploadDir.'/'.$filename;
        }

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

    /**
     * AI 스크린샷 분석
     */
    public function analyze(Request $request): JsonResponse
    {
        $request->validate([
            'paths' => 'required|array|min:1',
            'paths.*' => 'required|string',
        ]);

        $paths = $request->input('paths');

        // 파일 존재 확인
        foreach ($paths as $path) {
            if (! file_exists($path)) {
                return response()->json([
                    'success' => false,
                    'message' => '업로드된 파일을 찾을 수 없습니다: '.basename($path),
                ], 400);
            }
        }

        try {
            $analysisData = $this->screenAnalysisService->analyzeScreenshots($paths);
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('TutorialVideoController: 분석 예외', [
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'success' => false,
                'message' => 'AI 분석 중 오류가 발생했습니다: '.$e->getMessage(),
            ], 500);
        }

        if (empty($analysisData)) {
            return response()->json([
                'success' => false,
                'message' => '스크린샷 분석에 실패했습니다. AI 설정을 확인해주세요.',
            ], 500);
        }

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

    /**
     * 영상 생성 시작 (Job dispatch)
     */
    public function generate(Request $request): JsonResponse
    {
        $request->validate([
            'paths' => 'required|array|min:1',
            'analysis' => 'required|array',
            'title' => 'nullable|string|max:500',
        ]);

        $paths = $request->input('paths');
        $analysis = $request->input('analysis');
        $title = $request->input('title', 'SAM 사용자 매뉴얼');

        // DB 레코드 생성
        $tutorial = TutorialVideo::create([
            'tenant_id' => session('selected_tenant_id'),
            'user_id' => auth()->id(),
            'title' => $title,
            'status' => TutorialVideo::STATUS_PENDING,
            'screenshots' => $paths,
            'analysis_data' => $analysis,
        ]);

        // Job dispatch
        TutorialVideoJob::dispatch($tutorial->id);

        return response()->json([
            'success' => true,
            'id' => $tutorial->id,
            'message' => '영상 생성이 시작되었습니다.',
        ]);
    }

    /**
     * 진행 상태 폴링
     */
    public function status(int $id): JsonResponse
    {
        $tutorial = TutorialVideo::findOrFail($id);

        return response()->json([
            'id' => $tutorial->id,
            'status' => $tutorial->status,
            'progress' => $tutorial->progress,
            'current_step' => $tutorial->current_step,
            'error_message' => $tutorial->error_message,
            'output_path' => $tutorial->output_path ? true : false,
            'cost_usd' => $tutorial->cost_usd,
            'updated_at' => $tutorial->updated_at?->toIso8601String(),
            'created_at' => $tutorial->created_at?->toIso8601String(),
        ]);
    }

    /**
     * 완성 영상 다운로드
     */
    public function download(int $id): BinaryFileResponse|RedirectResponse|JsonResponse
    {
        $tutorial = TutorialVideo::findOrFail($id);

        if ($tutorial->status !== TutorialVideo::STATUS_COMPLETED || ! $tutorial->output_path) {
            return response()->json(['message' => '아직 영상이 완성되지 않았습니다.'], 404);
        }

        // GCS 서명URL
        if ($tutorial->gcs_path && $this->gcsService->isAvailable()) {
            $signedUrl = $this->gcsService->getSignedUrl($tutorial->gcs_path, 30);
            if ($signedUrl) {
                return redirect()->away($signedUrl);
            }
        }

        if (! file_exists($tutorial->output_path)) {
            return response()->json(['message' => '영상 파일을 찾을 수 없습니다.'], 404);
        }

        $filename = 'tutorial_'.($tutorial->title ? preg_replace('/[^a-zA-Z0-9가-힣_\-.]/', '_', $tutorial->title) : $tutorial->id).'.mp4';

        return response()->download($tutorial->output_path, $filename, [
            'Content-Type' => 'video/mp4',
        ]);
    }

    /**
     * 영상 미리보기 (스트리밍 또는 서명URL)
     *
     * ?url=1 파라미터: JSON으로 서명URL 반환 (CORS 회피용)
     * 그 외: 로컬 파일 직접 스트리밍
     */
    public function preview(Request $request, int $id): Response|RedirectResponse|JsonResponse|BinaryFileResponse
    {
        $tutorial = TutorialVideo::findOrFail($id);

        // ?url=1 → JSON으로 GCS 서명URL 반환 (video src에서 직접 사용)
        if ($request->query('url') && $tutorial->gcs_path && $this->gcsService->isAvailable()) {
            $signedUrl = $this->gcsService->getSignedUrl($tutorial->gcs_path, 60);
            if ($signedUrl) {
                return response()->json(['url' => $signedUrl]);
            }
        }

        // 로컬 파일 직접 스트리밍
        if (! $tutorial->output_path || ! file_exists($tutorial->output_path)) {
            return response()->json(['message' => '영상 파일을 찾을 수 없습니다.'], 404);
        }

        return response()->file($tutorial->output_path, [
            'Content-Type' => 'video/mp4',
            'Content-Length' => filesize($tutorial->output_path),
            'Accept-Ranges' => 'bytes',
        ]);
    }

    /**
     * 생성 이력 목록
     */
    public function history(): JsonResponse
    {
        $tutorials = TutorialVideo::where('user_id', auth()->id())
            ->orderByDesc('created_at')
            ->limit(50)
            ->get(['id', 'title', 'status', 'progress', 'cost_usd', 'created_at', 'updated_at']);

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

    /**
     * 이력 상세 (스크립트/분석 데이터)
     */
    public function detail(int $id): JsonResponse
    {
        $tutorial = TutorialVideo::where('user_id', auth()->id())
            ->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $tutorial->id,
                'title' => $tutorial->title,
                'status' => $tutorial->status,
                'progress' => $tutorial->progress,
                'analysis_data' => $tutorial->analysis_data,
                'slides_data' => $tutorial->slides_data,
                'cost_usd' => $tutorial->cost_usd,
                'created_at' => $tutorial->created_at?->toIso8601String(),
            ],
        ]);
    }

    /**
     * 이력 삭제
     */
    public function destroy(Request $request): JsonResponse
    {
        $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer',
        ]);

        $tutorials = TutorialVideo::where('user_id', auth()->id())
            ->whereIn('id', $request->input('ids'))
            ->get();

        $deleted = 0;
        foreach ($tutorials as $tutorial) {
            // GCS 파일 삭제
            if ($tutorial->gcs_path && $this->gcsService->isAvailable()) {
                $this->gcsService->delete($tutorial->gcs_path);
            }

            // 로컬 작업 디렉토리 삭제
            $workDir = storage_path("app/tutorial_gen/{$tutorial->id}");
            if (is_dir($workDir)) {
                $files = glob("{$workDir}/*");
                foreach ($files as $file) {
                    if (is_file($file)) {
                        @unlink($file);
                    }
                }
                @rmdir($workDir);
            }

            // 업로드된 원본 삭제
            $screenshots = $tutorial->screenshots ?? [];
            foreach ($screenshots as $path) {
                if (file_exists($path)) {
                    @unlink($path);
                }
            }
            // 업로드 디렉토리도 정리
            if (! empty($screenshots) && isset($screenshots[0])) {
                $uploadDir = dirname($screenshots[0]);
                if (is_dir($uploadDir)) {
                    @rmdir($uploadDir);
                }
            }

            $tutorial->delete();
            $deleted++;
        }

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