<?php

namespace App\Http\Controllers\Api\V1;

use App\Enums\ClothingOccasion;
use App\Enums\ClothingSeason;
use App\Enums\ClothingType;
use App\Http\Controllers\Controller;
use App\Http\Requests\ClothingItemRequest;
use App\Http\Resources\ClothingItemCollection;
use App\Http\Resources\ClothingItemResource;
use App\Models\ClothingItem;
use App\Services\ClothingRecognitionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;

class WardrobeController extends Controller
{
    public function index(Request $request): ClothingItemCollection
    {
        $query = $request->user()->clothingItems()->latest();

        if ($request->filled('search')) {
            $query->where('name', 'like', '%'.$request->string('search').'%');
        }

        if ($request->filled('type')) {
            $query->where('type', $request->string('type'));
        }

        if ($request->filled('season')) {
            $query->where('season', $request->string('season'));
        }

        if ($request->filled('occasion')) {
            $query->where('occasion', $request->string('occasion'));
        }

        $perPage = min((int) $request->input('per_page', 15), 100);

        return new ClothingItemCollection($query->paginate($perPage));
    }

    public function store(ClothingItemRequest $request): JsonResponse
    {
        $data = $request->validated();

        if ($request->hasFile('image')) {
            $data['image_path'] = $request->file('image')->store('clothing', 'public');
        }

        unset($data['image']);

        $item = new ClothingItem($data);
        $item->user_id = $request->user()->id;
        $item->save();

        return (new ClothingItemResource($item))
            ->response()
            ->setStatusCode(201);
    }

    public function batchStore(Request $request): JsonResponse
    {
        $request->validate([
            'items' => ['required', 'array', 'min:1'],
            'items.*.name' => ['required', 'string', 'max:255'],
            'items.*.type' => ['required', Rule::enum(ClothingType::class)],
            'items.*.color' => ['required', 'string', 'max:255'],
            'items.*.season' => ['required', Rule::enum(ClothingSeason::class)],
            'items.*.occasion' => ['required', Rule::enum(ClothingOccasion::class)],
            'items.*.brand' => ['nullable', 'string', 'max:255'],
            'photo' => ['required', 'image', 'max:4096'],
            'images' => ['nullable', 'array'],
            'images.*' => ['image', 'max:4096'],
        ]);

        $photo = $request->file('photo');
        $croppedImages = $request->file('images', []);
        $created = [];

        foreach ($request->input('items') as $idx => $itemData) {
            $data = [
                'name' => $itemData['name'],
                'type' => $itemData['type'],
                'color' => $itemData['color'],
                'season' => $itemData['season'],
                'occasion' => $itemData['occasion'],
                'brand' => $itemData['brand'] ?? null,
            ];

            $imageFile = $croppedImages[$idx] ?? $photo;
            $data['image_path'] = $imageFile->store('clothing', 'public');

            $item = new ClothingItem($data);
            $item->user_id = $request->user()->id;
            $item->save();
            $created[] = $item;
        }

        return ClothingItemResource::collection($created)
            ->response()
            ->setStatusCode(201);
    }

    public function show(Request $request, ClothingItem $clothingItem): ClothingItemResource
    {
        abort_unless($clothingItem->user_id === $request->user()->id, 403);

        return new ClothingItemResource($clothingItem);
    }

    public function update(ClothingItemRequest $request, ClothingItem $clothingItem): ClothingItemResource
    {
        abort_unless($clothingItem->user_id === $request->user()->id, 403);

        $data = $request->validated();

        if ($request->hasFile('image')) {
            if ($clothingItem->image_path) {
                Storage::disk('public')->delete($clothingItem->image_path);
            }
            $data['image_path'] = $request->file('image')->store('clothing', 'public');
        }

        unset($data['image']);

        $clothingItem->fill($data);
        $clothingItem->save();

        return new ClothingItemResource($clothingItem);
    }

    public function recognize(Request $request, ClothingRecognitionService $service): JsonResponse
    {
        $request->validate([
            'photo' => ['required', 'image', 'max:4096'],
        ]);

        $result = $service->recognizeFromPhoto($request->file('photo'), $request->user()->id);

        if (isset($result['error'])) {
            return response()->json(['error' => $result['error']], 422);
        }

        return response()->json($result);
    }

    public function isolateItem(Request $request, ClothingRecognitionService $service): JsonResponse
    {
        $request->validate([
            'photo' => ['required', 'image', 'max:4096'],
            'description' => ['required', 'string', 'max:500'],
        ]);

        $result = $service->isolateClothingItem(
            $request->file('photo'),
            $request->input('description'),
            $request->user()->id,
        );

        if (isset($result['error'])) {
            return response()->json(['error' => $result['error']], 422);
        }

        return response()->json($result);
    }

    public function destroy(Request $request, ClothingItem $clothingItem): JsonResponse
    {
        abort_unless($clothingItem->user_id === $request->user()->id, 403);

        if ($clothingItem->image_path) {
            Storage::disk('public')->delete($clothingItem->image_path);
        }

        $clothingItem->delete();

        return response()->json(null, 204);
    }
}
