<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\Models\Conversation;
use App\Models\ConversationParticipant;
use App\Models\Message;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class MessageController extends Controller
{
    public function index()
    {
        $user = Auth::user();

        try {
            $conversations = $user->conversations()
                ->with(['participants', 'lastMessage.user'])
                ->orderByDesc('conversations.updated_at')
                ->get()
                ->map(function ($conv) use ($user) {
                    $other = $conv->participants->firstWhere('id', '!=', $user->id);
                    return [
                        'id'           => $conv->id,
                        'other'        => $other,
                        'last_message' => $conv->lastMessage,
                        'unread'       => $conv->unreadCountFor($user->id),
                        'updated_at'   => $conv->updated_at,
                    ];
                });
        } catch (\Throwable $e) {
            $conversations = collect();
        }

        return view('frontend.messages.index', compact('conversations'));
    }

    public function show(Conversation $conversation)
    {
        $user = Auth::user();

        abort_unless(
            $conversation->participants()->where('user_id', $user->id)->exists(),
            403
        );

        $other = $conversation->participants()->where('user_id', '!=', $user->id)->first();

        $messages = $conversation->messages()
            ->with('user')
            ->orderBy('created_at')
            ->get();

        // Mark as read
        $conversation->participants()
            ->updateExistingPivot($user->id, ['last_read_at' => now()]);

        return view('frontend.messages.show', compact('conversation', 'messages', 'other'));
    }

    public function startOrOpen(User $user)
    {
        $me = Auth::user();

        if ($me->id === $user->id) abort(422);

        // Find existing conversation between these two users
        $conv = Conversation::whereHas('participants', fn($q) => $q->where('user_id', $me->id))
            ->whereHas('participants', fn($q) => $q->where('user_id', $user->id))
            ->first();

        if (!$conv) {
            $conv = DB::transaction(function () use ($me, $user) {
                $c = Conversation::create();
                $c->participants()->attach([$me->id, $user->id]);
                return $c;
            });
        }

        return redirect()->route('messages.show', $conv);
    }

    public function send(Request $request, Conversation $conversation)
    {
        $user = Auth::user();

        abort_unless(
            $conversation->participants()->where('user_id', $user->id)->exists(),
            403
        );

        $request->validate(['body' => 'required|string|max:5000']);

        $message = Message::create([
            'conversation_id' => $conversation->id,
            'user_id'         => $user->id,
            'body'            => $request->body,
        ]);

        $conversation->touch();

        // Mark sender as read
        $conversation->participants()
            ->updateExistingPivot($user->id, ['last_read_at' => now()]);

        if ($request->expectsJson()) {
            return response()->json([
                'id'         => $message->id,
                'body'       => $message->body,
                'user_id'    => $user->id,
                'created_at' => $message->created_at->format('H:i'),
                'avatar'     => $user->avatar ? \App\Support\MediaUrl::fromStoragePath($user->avatar) : null,
                'name'       => $user->name,
            ]);
        }

        return back();
    }

    public function poll(Request $request, Conversation $conversation)
    {
        $user = Auth::user();

        abort_unless(
            $conversation->participants()->where('user_id', $user->id)->exists(),
            403
        );

        $after = $request->query('after', 0);

        $messages = $conversation->messages()
            ->with('user')
            ->where('id', '>', $after)
            ->orderBy('created_at')
            ->get()
            ->map(fn($m) => [
                'id'         => $m->id,
                'body'       => $m->body,
                'user_id'    => $m->user_id,
                'created_at' => $m->created_at->format('H:i'),
                'avatar'     => $m->user->avatar ? \App\Support\MediaUrl::fromStoragePath($m->user->avatar) : null,
                'name'       => $m->user->name,
            ]);

        // Update last_read
        $conversation->participants()
            ->updateExistingPivot($user->id, ['last_read_at' => now()]);

        return response()->json(['messages' => $messages]);
    }

    public function unreadCount()
    {
        $user = Auth::user();
        if (!$user) return response()->json(['count' => 0]);

        $count = 0;
        foreach ($user->conversations()->with(['messages'])->get() as $conv) {
            $count += $conv->unreadCountFor($user->id);
        }

        return response()->json(['count' => $count]);
    }

    public function conversationsJson()
    {
        $user = Auth::user();

        $convs = $user->conversations()
            ->with(['participants', 'lastMessage.user'])
            ->orderByDesc('conversations.updated_at')
            ->limit(30)
            ->get()
            ->map(function ($conv) use ($user) {
                $other   = $conv->participants->firstWhere('id', '!=', $user->id);
                $last    = $conv->lastMessage;
                $unread  = $conv->unreadCountFor($user->id);

                $preview = null;
                if ($last) {
                    if (str_starts_with($last->body, 'ANIMESHARE::')) {
                        try { $sd = json_decode(substr($last->body, 12), true); $preview = '🎬 ' . ($sd['title'] ?? 'Anime paylaştı'); } catch(\Throwable) {}
                    } elseif (str_starts_with($last->body, 'IMAGE::')) {
                        $preview = ($last->user_id === $user->id ? 'Sen: ' : '') . '📷 Fotoğraf';
                    } elseif (str_starts_with($last->body, 'GIF::')) {
                        $preview = ($last->user_id === $user->id ? 'Sen: ' : '') . '🎞 GIF';
                    } else {
                        $isMine  = $last->user_id === $user->id;
                        $preview = ($isMine ? 'Sen: ' : '') . \Illuminate\Support\Str::limit($last->body, 50);
                    }
                }

                return [
                    'conv_id'      => $conv->id,
                    'id'           => $other?->id,
                    'name'         => $other?->name ?? 'Silinmiş',
                    'avatar'       => $other?->avatar ? \App\Support\MediaUrl::fromStoragePath($other->avatar) : null,
                    'last_preview' => $preview,
                    'unread'       => $unread,
                    'time'         => $conv->updated_at ? $conv->updated_at->diffForHumans(null, true) : null,
                ];
            });

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

    public function uploadImage(Request $request)
    {
        $request->validate([
            'image' => 'required|file|image|max:8192|mimes:jpeg,jpg,png,gif,webp',
        ]);

        $path = $request->file('image')->store('chat-images', 'public');
        $url  = Storage::disk('public')->url($path);

        return response()->json(['url' => $url]);
    }

    public function quickShare(Request $request)
    {
        $request->validate([
            'to_user_id' => 'required|integer|exists:users,id',
            'body'       => 'required|string|max:3000',
        ]);

        $me     = Auth::user();
        $target = User::findOrFail($request->to_user_id);

        if ($me->id === $target->id) abort(422, 'Kendinize gönderemezsiniz.');

        $conv = Conversation::whereHas('participants', fn($q) => $q->where('user_id', $me->id))
            ->whereHas('participants', fn($q) => $q->where('user_id', $target->id))
            ->first();

        if (!$conv) {
            $conv = DB::transaction(function () use ($me, $target) {
                $c = Conversation::create();
                $c->participants()->attach([$me->id, $target->id]);
                return $c;
            });
        }

        $message = Message::create([
            'conversation_id' => $conv->id,
            'user_id'         => $me->id,
            'body'            => $request->body,
        ]);

        $conv->touch();
        $conv->participants()->updateExistingPivot($me->id, ['last_read_at' => now()]);

        return response()->json([
            'ok'              => true,
            'conversation_id' => $conv->id,
            'message_id'      => $message->id,
        ]);
    }
}
