<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use OpenApi\Attributes as OA;

class UploadController extends Controller
{
    #[OA\Post(
        path: '/api/admin/upload',
        summary: 'Dosya yükle',
        description: 'Görsel veya video dosyası yükler. Görseller max 5MB, videolar max 100MB. Modül bazlı klasörleme destekler.',
        security: [['sanctum' => []]],
        tags: ['Upload'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\MediaType(
                mediaType: 'multipart/form-data',
                schema: new OA\Schema(
                    required: ['file'],
                    properties: [
                        new OA\Property(property: 'file', type: 'string', format: 'binary', description: 'Görsel veya video dosyası'),
                        new OA\Property(property: 'type', type: 'string', enum: ['image', 'video'], description: 'Dosya tipi'),
                        new OA\Property(property: 'folder', type: 'string', description: 'Modül klasörü (hero-slides, courses, vb.)'),
                    ],
                ),
            ),
        ),
        responses: [
            new OA\Response(response: 201, description: 'Dosya yüklendi', content: new OA\JsonContent(
                properties: [
                    new OA\Property(property: 'data', type: 'object', properties: [
                        new OA\Property(property: 'path', type: 'string'),
                        new OA\Property(property: 'url', type: 'string'),
                    ]),
                ],
            )),
            new OA\Response(response: 422, description: 'Validasyon hatası'),
        ],
    )]
    public function store(Request $request): JsonResponse
    {
        $type = $request->input('type', 'image');

        if ($type === 'video') {
            return $this->storeVideo($request);
        }

        return $this->storeImage($request);
    }

    /**
     * @var list<string>
     */
    private const ALLOWED_FOLDERS = [
        'images',
        'videos',
        'hero-slides',
        'settings',
        'pages',
        'courses',
        'announcements',
        'categories',
    ];

    private function resolveFolder(Request $request, string $default): string
    {
        $folder = $request->input('folder', $default);

        if (! in_array($folder, self::ALLOWED_FOLDERS, true)) {
            $folder = $default;
        }

        return $folder;
    }

    private function storeImage(Request $request): JsonResponse
    {
        $request->validate([
            'file' => ['required', 'file', 'image', 'max:5120'],
            'folder' => ['sometimes', 'string'],
        ], [
            'file.required' => 'Dosya zorunludur.',
            'file.image' => 'Dosya bir görsel (jpg, png, gif, svg, webp) olmalıdır.',
            'file.max' => 'Dosya boyutu en fazla 5MB olabilir.',
        ]);

        $folder = $this->resolveFolder($request, 'images');

        $file = $request->file('file');
        $filename = Str::uuid().'.'.$file->getClientOriginalExtension();

        $directory = public_path('uploads/'.$folder);
        $file->move($directory, $filename);

        $relativePath = 'uploads/'.$folder.'/'.$filename;

        return response()->json([
            'data' => [
                'path' => $relativePath,
                'url' => url($relativePath),
            ],
        ], 201);
    }

    private function storeVideo(Request $request): JsonResponse
    {
        $request->validate([
            'file' => ['required', 'file', 'mimes:mp4,webm,mov,avi,mkv', 'max:102400'],
            'folder' => ['sometimes', 'string'],
        ], [
            'file.required' => 'Dosya zorunludur.',
            'file.mimes' => 'Dosya bir video (mp4, webm, mov, avi, mkv) olmalıdır.',
            'file.max' => 'Video boyutu en fazla 100MB olabilir.',
        ]);

        $folder = $this->resolveFolder($request, 'videos');

        $file = $request->file('file');
        $filename = Str::uuid().'.'.$file->getClientOriginalExtension();

        $directory = public_path('uploads/'.$folder);
        $file->move($directory, $filename);

        $relativePath = 'uploads/'.$folder.'/'.$filename;

        return response()->json([
            'data' => [
                'path' => $relativePath,
                'url' => url($relativePath),
            ],
        ], 201);
    }
}
