<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api;

use App\Enums\ConversationStatus;
use App\Http\Controllers\Controller;
use App\Http\Resources\Dashboard\InboxConversationSummaryResource;
use App\Http\Resources\Dashboard\MyProposalSummaryResource;
use App\Http\Resources\Dashboard\MyRequestSummaryResource;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\PropertyProposal;
use App\Models\PropertyRequest;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class DashboardController extends Controller
{
    /**
     * § 13.2 — demandes publiées par l’utilisateur connecté.
     */
    public function myRequests(Request $request): AnonymousResourceCollection
    {
        $user = $request->user();
        $requestTable = (new PropertyRequest)->getTable();
        $conversationTable = (new Conversation)->getTable();
        $messageTable = (new Message)->getTable();

        $lastMessageBody = Message::query()
            ->select("{$messageTable}.message")
            ->join($conversationTable, "{$conversationTable}.id", '=', "{$messageTable}.conversation_id")
            ->whereColumn("{$conversationTable}.request_id", "{$requestTable}.id")
            ->orderByDesc("{$messageTable}.id")
            ->limit(1);

        $lastMessageIsSystem = Message::query()
            ->select("{$messageTable}.is_system")
            ->join($conversationTable, "{$conversationTable}.id", '=', "{$messageTable}.conversation_id")
            ->whereColumn("{$conversationTable}.request_id", "{$requestTable}.id")
            ->orderByDesc("{$messageTable}.id")
            ->limit(1);

        $lastMessageAt = Message::query()
            ->select("{$messageTable}.created_at")
            ->join($conversationTable, "{$conversationTable}.id", '=', "{$messageTable}.conversation_id")
            ->whereColumn("{$conversationTable}.request_id", "{$requestTable}.id")
            ->orderByDesc("{$messageTable}.id")
            ->limit(1);

        $paginator = PropertyRequest::query()
            ->where('created_by_user_id', $user->id)
            ->select("{$requestTable}.*")
            ->selectSub($lastMessageBody, 'last_message_preview')
            ->selectSub($lastMessageIsSystem, 'last_message_is_system')
            ->selectSub($lastMessageAt, 'last_message_at')
            ->withCount(['proposals as responses_count'])
            ->orderByDesc('updated_at')
            ->paginate(15);

        return MyRequestSummaryResource::collection($paginator);
    }

    /**
     * § 13.5 — propositions envoyées par l’utilisateur.
     */
    public function myProposals(Request $request): AnonymousResourceCollection
    {
        $user = $request->user();

        $paginator = PropertyProposal::query()
            ->where('proposed_by_user_id', $user->id)
            ->with(['photos'])
            ->with([
                'conversation' => function ($q) use ($user): void {
                    $q->with('latestMessage')
                        ->withCount([
                            'messages as unread_count' => function ($m) use ($user): void {
                                $m->whereNull('read_at')->where('sender_id', '!=', $user->id);
                            },
                        ]);
                },
            ])
            ->join('conversations', 'conversations.proposal_id', '=', 'property_proposals.id')
            ->select('property_proposals.*')
            ->orderByDesc('conversations.updated_at')
            ->paginate(15);

        return MyProposalSummaryResource::collection($paginator);
    }

    /**
     * § 13.1 / 13.6 — conversations actives (non terminées), tri par dernière activité.
     */
    public function inbox(Request $request): AnonymousResourceCollection
    {
        $user = $request->user();

        $paginator = Conversation::query()
            ->where(static function ($q) use ($user): void {
                $q->where('requester_user_id', $user->id)
                    ->orWhere('proposer_user_id', $user->id);
            })
            ->whereNotIn('status', [
                ConversationStatus::DealClosed->value,
                ConversationStatus::DealCancelled->value,
            ])
            ->with(['latestMessage', 'requester:id,name', 'proposer:id,name', 'request:id,property_type'])
            ->withCount([
                'messages as unread_count' => function ($q) use ($user): void {
                    $q->whereNull('read_at')->where('sender_id', '!=', $user->id);
                },
            ])
            ->orderByDesc('updated_at')
            ->paginate(15);

        return InboxConversationSummaryResource::collection($paginator);
    }
}
