<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Anime;
use App\Models\AnimeRating;
use App\Models\AnimeFollow;
use App\Models\ContinueWatching;
use App\Models\EpisodeVote;
use App\Models\EpisodeNote;
use App\Models\UserNotification;
use App\Models\UserAchievement;
use App\Models\Achievement;
use App\Models\Watchlist;
use App\Models\AnimeRequest;
use App\Models\AnimeRequestVote;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UserApiController extends Controller
{
    // ── Watchlist ──────────────────────────────────────────────────────────────

    public function watchlist(Request $request)
    {
        $status = $request->input('status'); // watching|completed|plan_to_watch|dropped

        $query = Watchlist::where('user_id', $request->user()->id)
            ->with('anime:id,title,slug,cover_image,rating,episode_count,status,release_year');

        if ($status) $query->where('status', $status);

        $items = $query->orderByDesc('updated_at')->paginate(24);

        return response()->json([
            'data' => collect($items->items())->map(fn($w) => [
                'id'     => $w->id,
                'status' => $w->status,
                'anime'  => $w->anime ? [
                    'id'            => $w->anime->id,
                    'title'         => $w->anime->title,
                    'slug'          => $w->anime->slug,
                    'cover_url'     => \App\Support\MediaUrl::fromStoragePath($w->anime->cover_image),
                    'rating'        => $w->anime->rating,
                    'episode_count' => $w->anime->episode_count,
                    'status'        => $w->anime->status,
                    'release_year'  => $w->anime->release_year,
                ] : null,
            ]),
            'total'    => $items->total(),
            'last_page'=> $items->lastPage(),
        ]);
    }

    public function watchlistToggle(Request $request, Anime $anime)
    {
        $user   = $request->user();
        $status = $request->input('status', 'plan_to_watch');

        $existing = Watchlist::where('user_id', $user->id)->where('anime_id', $anime->id)->first();

        if ($existing) {
            if ($existing->status === $status) {
                $existing->delete();
                return response()->json(['in_watchlist' => false, 'status' => null]);
            }
            $existing->update(['status' => $status]);
            return response()->json(['in_watchlist' => true, 'status' => $status]);
        }

        Watchlist::create(['user_id' => $user->id, 'anime_id' => $anime->id, 'status' => $status]);
        return response()->json(['in_watchlist' => true, 'status' => $status]);
    }

    // ── Continue Watching ──────────────────────────────────────────────────────

    public function continueWatchingUpdate(Request $request)
    {
        $data = $request->validate([
            'anime_id'         => 'required|exists:animes,id',
            'season_number'    => 'required|integer|min:1',
            'episode_number'   => 'required|integer|min:1',
            'percent_complete' => 'required|numeric|min:0|max:100',
        ]);

        ContinueWatching::updateOrCreate(
            ['user_id' => $request->user()->id, 'anime_id' => $data['anime_id']],
            [
                'season_number'    => $data['season_number'],
                'episode_number'   => $data['episode_number'],
                'percent_complete' => $data['percent_complete'],
            ]
        );

        return response()->json(['ok' => true]);
    }

    // ── Anime Rate ─────────────────────────────────────────────────────────────

    public function animeRate(Request $request, Anime $anime)
    {
        $data = $request->validate(['rating' => 'required|numeric|min:1|max:10']);

        AnimeRating::updateOrCreate(
            ['user_id' => $request->user()->id, 'anime_id' => $anime->id],
            ['rating'  => $data['rating']]
        );

        $avg = AnimeRating::where('anime_id', $anime->id)->avg('rating');
        $anime->update(['rating' => round($avg, 1)]);

        return response()->json(['rating' => $data['rating'], 'avg' => round($avg, 1)]);
    }

    // ── Follow ─────────────────────────────────────────────────────────────────

    public function followToggle(Request $request, Anime $anime)
    {
        $user = $request->user();
        $existing = AnimeFollow::where('user_id', $user->id)->where('anime_id', $anime->id)->first();

        if ($existing) {
            $existing->delete();
            return response()->json(['following' => false]);
        }

        AnimeFollow::create(['user_id' => $user->id, 'anime_id' => $anime->id]);
        return response()->json(['following' => true]);
    }

    // ── Notifications ──────────────────────────────────────────────────────────

    public function notifications(Request $request)
    {
        $items = UserNotification::where('user_id', $request->user()->id)
            ->orderByDesc('created_at')->paginate(20);

        // Mark all as read
        UserNotification::where('user_id', $request->user()->id)->whereNull('read_at')->update(['read_at' => now()]);

        return response()->json([
            'data' => collect($items->items())->map(fn($n) => [
                'id'         => $n->id,
                'type'       => $n->type,
                'data'       => $n->data ?? [],
                'is_read'    => $n->is_read,
                'created_at' => $n->created_at?->diffForHumans(),
            ]),
            'total'    => $items->total(),
            'last_page'=> $items->lastPage(),
        ]);
    }

    public function notificationsCount(Request $request)
    {
        if (!$request->user()) return response()->json(['count' => 0]);
        $count = UserNotification::where('user_id', $request->user()->id)->whereNull('read_at')->count();
        return response()->json(['count' => $count]);
    }

    // ── Achievements ───────────────────────────────────────────────────────────

    public function achievements(Request $request)
    {
        $all     = Achievement::orderBy('points')->get();
        $earned  = UserAchievement::where('user_id', $request->user()->id)->pluck('achievement_id')->toArray();
        $total   = UserAchievement::where('user_id', $request->user()->id)->join('achievements','achievements.id','=','user_achievements.achievement_id')->sum('achievements.points');

        return response()->json([
            'total_points' => (int)$total,
            'data' => $all->map(fn($a) => [
                'id'          => $a->id,
                'name'        => $a->name,
                'description' => $a->description,
                'icon'        => $a->icon,
                'points'      => $a->points,
                'earned'      => in_array($a->id, $earned),
                'earned_at'   => in_array($a->id, $earned)
                    ? UserAchievement::where('user_id', $request->user()->id)->where('achievement_id', $a->id)->value('created_at')?->toISOString()
                    : null,
            ]),
        ]);
    }

    // ── Episode Notes ──────────────────────────────────────────────────────────

    public function noteStore(Request $request, $episodeId)
    {
        $data = $request->validate(['note' => 'required|string|max:1000']);

        $note = EpisodeNote::create([
            'user_id'    => $request->user()->id,
            'episode_id' => $episodeId,
            'note'       => $data['note'],
        ]);

        return response()->json(['id' => $note->id, 'note' => $note->note, 'created_at' => $note->created_at?->toISOString()], 201);
    }

    public function noteDelete(Request $request, $noteId)
    {
        $note = EpisodeNote::where('id', $noteId)->where('user_id', $request->user()->id)->firstOrFail();
        $note->delete();
        return response()->json(['ok' => true]);
    }

    public function episodeNotesList(Request $request, $episodeId)
    {
        $notes = EpisodeNote::where('user_id', $request->user()->id)
            ->where('episode_id', $episodeId)
            ->orderByDesc('created_at')->get();

        return response()->json($notes->map(fn($n) => [
            'id'         => $n->id,
            'note'       => $n->note,
            'created_at' => $n->created_at?->toISOString(),
        ]));
    }

    // ── Anime Requests ─────────────────────────────────────────────────────────

    public function requestIndex(Request $request)
    {
        $items = AnimeRequest::withCount('votes')
            ->orderByDesc('votes_count')->orderByDesc('created_at')->paginate(20);

        return response()->json([
            'data' => collect($items->items())->map(fn($r) => [
                'id'          => $r->id,
                'title'       => $r->title,
                'note'        => $r->note,
                'status'      => $r->status,
                'votes_count' => $r->votes_count,
                'created_at'  => $r->created_at?->diffForHumans(),
                'user_voted'  => $request->user()
                    ? AnimeRequestVote::where('user_id', $request->user()->id)->where('anime_request_id', $r->id)->exists()
                    : false,
            ]),
            'total'    => $items->total(),
            'last_page'=> $items->lastPage(),
        ]);
    }

    public function requestStore(Request $request)
    {
        $data = $request->validate([
            'title' => 'required|string|max:200',
            'note'  => 'nullable|string|max:500',
        ]);

        $req = AnimeRequest::create([
            'user_id' => $request->user()->id,
            'title'   => $data['title'],
            'note'    => $data['note'] ?? null,
            'status'  => 'pending',
        ]);

        return response()->json(['id' => $req->id, 'title' => $req->title], 201);
    }

    public function requestVote(Request $request, AnimeRequest $animeRequest)
    {
        $user = $request->user();
        $existing = AnimeRequestVote::where('user_id', $user->id)->where('anime_request_id', $animeRequest->id)->first();

        if ($existing) {
            $existing->delete();
            return response()->json(['voted' => false, 'votes' => $animeRequest->votes()->count()]);
        }

        AnimeRequestVote::create(['user_id' => $user->id, 'anime_request_id' => $animeRequest->id]);
        return response()->json(['voted' => true, 'votes' => $animeRequest->votes()->count()]);
    }

    // ── Profile Stats ──────────────────────────────────────────────────────────

    public function profileStats(Request $request)
    {
        $userId = $request->user()->id;

        $watchlistCount   = Watchlist::where('user_id', $userId)->count();
        $completedCount   = Watchlist::where('user_id', $userId)->where('status', 'completed')->count();
        $notifCount       = UserNotification::where('user_id', $userId)->where('is_read', false)->count();
        $achPoints        = UserAchievement::where('user_id', $userId)
            ->join('achievements','achievements.id','=','user_achievements.achievement_id')
            ->sum('achievements.points');
        $achCount         = UserAchievement::where('user_id', $userId)->count();
        $commentCount     = \App\Models\Comment::where('user_id', $userId)->count();

        return response()->json([
            'watchlist_count'   => $watchlistCount,
            'completed_count'   => $completedCount,
            'notif_count'       => (int)$notifCount,
            'achievement_points'=> (int)$achPoints,
            'achievement_count' => $achCount,
            'comment_count'     => $commentCount,
        ]);
    }
}
