<?php

namespace App\Http\Controllers;

use App\Models\Album;
use App\Models\Track;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class TrackController extends Controller
{
    public function index(): JsonResponse
    {
        return response()->json(Track::with(['album', 'artists', 'genres'])->orderBy('position')->get());
    }

    public function show(Track $track): JsonResponse
    {
        return response()->json($track->load(['album.label', 'artists', 'genres']));
    }

    public function store(Request $request): JsonResponse
    {
        $data = $request->validate([
            'title'            => 'required|string|max:255',
            'file_path'        => 'required|string|max:255',
            'duration_seconds' => 'nullable|integer',
            'album_id'         => 'nullable|exists:albums,id',
            'position'         => 'nullable|integer',
            'artist_ids'       => 'nullable|array',
            'artist_ids.*'     => 'exists:artists,id',
            'genre_ids'        => 'nullable|array',
            'genre_ids.*'      => 'exists:genres,id',
        ]);

        if (!isset($data['position']) && isset($data['album_id'])) {
            $data['position'] = Track::where('album_id', $data['album_id'])->max('position') + 1;
        }

        $track = Track::create($data);

        if (!empty($data['artist_ids'])) {
            $track->artists()->sync($data['artist_ids']);
        }

        if (!empty($data['genre_ids'])) {
            $track->genres()->sync($data['genre_ids']);
        }

        return response()->json($track->load(['album', 'artists', 'genres']), 201);
    }

    public function update(Request $request, Track $track): JsonResponse
    {
        $data = $request->validate([
            'title'            => 'sometimes|required|string|max:255',
            'file_path'        => 'sometimes|required|string|max:255',
            'duration_seconds' => 'nullable|integer',
            'album_id'         => 'nullable|exists:albums,id',
            'position'         => 'nullable|integer',
            'artist_ids'       => 'nullable|array',
            'artist_ids.*'     => 'exists:artists,id',
            'genre_ids'        => 'nullable|array',
            'genre_ids.*'      => 'exists:genres,id',
        ]);

        $track->update($data);

        if (array_key_exists('artist_ids', $data)) {
            $track->artists()->sync($data['artist_ids'] ?? []);
        }

        if (array_key_exists('genre_ids', $data)) {
            $track->genres()->sync($data['genre_ids'] ?? []);
        }

        return response()->json($track->load(['album', 'artists', 'genres']));
    }

    public function destroy(Track $track): JsonResponse
    {
        $track->delete();

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

    public function reorder(Request $request, Album $album): JsonResponse
    {
        $data = $request->validate([
            'positions'   => 'required|array',
            'positions.*.id'       => 'required|exists:tracks,id',
            'positions.*.position' => 'required|integer|min:0',
        ]);

        foreach ($data['positions'] as $item) {
            Track::where('id', $item['id'])
                ->where('album_id', $album->id)
                ->update(['position' => $item['position']]);
        }

        return response()->json(
            $album->load(['tracks.artists', 'tracks.genres'])->tracks->sortBy('position')->values()
        );
    }
}
