<?php

namespace App\Http\Controllers;

use Inertia\Inertia;
use App\Domain\Feeds\Models\Feed;
use App\Domain\Feeds\Enums\StatusEnum;
use App\Http\Requests\MusicFormRequest;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Database\Eloquent\Builder;
use App\Domain\Tags\Action\CreateTagAction;
use App\Domain\Feeds\Action\CreateFeedAction;
use App\Domain\Feeds\Queries\FeedQueryBuilder;
use App\Domain\Musics\Action\CreateMusicAction;
use App\Domain\Musics\Action\UpdateMusicAction;
use App\Domain\Feeds\Service\FeedMediaTransform;
use App\Domain\Musics\DataTransferObjects\MusicData;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class MusicsController extends Controller
{

    public function __construct()
    {
        $this->middleware('subs.paid')->except('loadedPlaylist', 'favoritePlaylist', 'show');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $filter = Request::get('filter');

        $feeds = (new FeedQueryBuilder())
            ->addType('music')
            ->search(Request::only('search'))
            ->enableAdvertising()
            ->filter($filter)
            ->build();
        $nextCursor = $feeds->nextCursor;
        $feeds = $feeds->transformData();

        if(request()->wantsJson()){
            return ['collections' => $feeds, 'next' => $nextCursor];
        }

        $route = route('musics.index');
        return Inertia::render('Music/Feed', [
            'nextCursor' => $nextCursor,
            'searchFilters' => Request::all('search'),
            'feeds' => $feeds,
            'local_route' => $route,
            'active_filter' => $filter ?? 'new'
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return Inertia::render('Music/Create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(MusicFormRequest $request)
    {
        $action = new CreateFeedAction(
            new CreateMusicAction(),
            new CreateTagAction(),
        );

        $musicData = MusicData::fromRequest($request);
        $action($musicData);
        $msg = 'Музыка успешно загружена и находится на модерации!';
        return Redirect::route('profile.user', auth()->user()->username)->with('success', $msg);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($slug)
    {
        $feed = new FeedQueryBuilder();
        $feed = $feed->selectBy('slug', $slug)->disablePaginate()->transformGet()->first();
        if(!$feed){
            abort(404);
        }
        return Inertia::render('Music/Show', [
            'user' => $feed['user'],
            'feed' =>  $feed,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($slug)
    {
        $feed = Feed::where('slug', $slug)->firstOrFail();

        if (!$feed->user()->is(auth()->user())) {
            abort(404);
        }
        $tags = $feed->tags()->pluck('name')->toArray();


        $mediaTransform = (new FeedMediaTransform($feed))->default();
        $mediaPreview = $mediaTransform->getPreviewObject();

        $mediaTransformCommon = $mediaTransform->spot();
        $mediaTransformPaid = (new FeedMediaTransform($feed))->paid()->spot();

        return Inertia::render('Music/Edit', [
            'feed' => $feed,
            'tags' => $tags,
            'mediaPreview' => $mediaPreview,
            'mediasCount' => count($mediaTransformCommon['medias']),
            'mediasCommon' => $mediaTransformCommon['medias'],
            'mediasPaid' => $mediaTransformPaid['medias'],
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(MusicFormRequest $request, Feed $feed)
    {
        $oldStatus = $feed->status;
        if (!$feed->user()->is(auth()->user())) {
            abort(404);
        }

        $action = new CreateFeedAction(
            new UpdateMusicAction($feed),
            new CreateTagAction(),
        );

        $musicData = MusicData::fromRequest($request);
        $action($musicData);
        $newStatus = $feed->status;

        $message = 'Аудио файл успешно обновлен!';
        if($oldStatus === StatusEnum::APPROVED() && $newStatus === StatusEnum::EDITABLE()){
            $message = 'Аудио файл успешно обновлен и находится на модерации!';
        }

        return Redirect::back()->with('success', $message);

    }



    public function loadedPlaylist()
    {

        $musics = Media::whereHasMorph(
            'model',
            [Feed::class],
            function (Builder $query) {
                $query->where('user_id', auth()->user()->id)->where('type', 'musics');
            }
        )->where('collection_name', '<>', 'preview')->orderBy('id', 'desc')->cursorPaginate(10);
        $cursor = get_cursor_hash($musics);

        $musics_collection = [];
        $musics->each(function ($media) use (&$musics_collection) {
                $musics_collection[] = [
                    'url' => $media->getFullUrl(),
                    'name' => $media->name,
                    'playing' => false,
                    'time' => $media->getCustomProperty('time'),
                    'id' => $media->id,
                ];
        });
        return ['collection' => $musics_collection, 'cursor' => $cursor];
    }

    public function favoritePlaylist()
    {
        $audios = auth()->user()->audioLike()->cursorPaginate(10);
        $cursor = get_cursor_hash($audios);

        $musics_collection = [];
        $audios->each(function ($media) use (&$musics_collection) {
                $musics_collection[] = [
                    'url' => $media->getFullUrl(),
                    'name' => $media->name,
                    'playing' => false,
                    'liked' => true,
                    'time' => $media->getCustomProperty('time'),
                    'id' => $media->id,
                ];
        });
        return ['collection' => $musics_collection, 'cursor' => $cursor];
    }



}
