<?php

namespace Modules\WhatsApp\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\WhatsApp\Entities\Services\ConversationService;
use Modules\WhatsApp\Entities\Services\WaSender;
use Modules\WhatsApp\Entities\WaConversation;
use Modules\WhatsApp\Entities\WaMessage;

class WaInboxController extends Controller
{
    public function index()
    {
        $this->authorizeView();
        $businessId = request()->session()->get('user.business_id');

        $conversations = $this->listQuery($businessId)->limit(100)->get();
        $quickReplies = \Modules\WhatsApp\Entities\WaTemplate::where('business_id', $businessId)
            ->where('active', true)->orderBy('name')->get(['name', 'body']);

        return view('whatsapp::inbox.index', compact('conversations', 'quickReplies'));
    }

    public function setLabels(Request $request, $id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        $labels = array_values(array_filter(array_map('trim', explode(',', (string) $request->input('labels', '')))));
        $conversation->forceFill(['labels' => $labels])->save();

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

    /** JSON conversation list (polled by the inbox for live updates). */
    public function list(Request $request)
    {
        $this->authorizeView();
        $businessId = request()->session()->get('user.business_id');

        $rows = $this->listQuery($businessId)->limit(100)->get()->map(function ($c) {
            return [
                'id'        => $c->id,
                'name'      => $c->displayName(),
                'wa_id'     => $c->wa_id,
                'excerpt'   => $c->last_message_excerpt,
                'at'        => optional($c->last_message_at)->diffForHumans(),
                'unread'    => $c->unread_count,
                'direction' => $c->last_direction,
                'assigned'  => $c->assigned_user_id ? optional($c->assignedUser)->first_name : null,
                'ai'        => (bool) $c->ai_enabled,
                'labels'    => $c->labels ?? [],
            ];
        });

        return response()->json([
            'conversations' => $rows,
            'total_unread'  => (int) WaConversation::where('business_id', $businessId)->sum('unread_count'),
        ]);
    }

    /** JSON message thread for one conversation; marks it read. */
    public function thread($id)
    {
        $this->authorizeView();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        (new ConversationService())->markRead($conversation);

        $messages = WaMessage::where('conversation_id', $conversation->id)
            ->orderBy('id')->limit(300)
            ->get(['id', 'direction', 'type', 'body', 'status', 'source', 'created_at']);

        return response()->json([
            'conversation' => [
                'id'          => $conversation->id,
                'name'        => $conversation->displayName(),
                'wa_id'       => $conversation->wa_id,
                'assigned_id' => $conversation->assigned_user_id,
                'assigned'    => optional($conversation->assignedUser)->first_name,
                'ai'          => (bool) $conversation->ai_enabled,
                'window_open' => $conversation->isWindowOpen(),
                'status'      => $conversation->status,
                'labels'      => $conversation->labels ?? [],
            ],
            'messages' => $messages->map(fn ($m) => [
                'id'        => $m->id,
                'direction' => $m->direction,
                'body'      => $m->body,
                'type'      => $m->type,
                'status'    => $m->status,
                'source'    => $m->source,
                'time'      => $m->created_at->format('H:i'),
                'date'      => $m->created_at->format('Y-m-d'),
            ]),
        ]);
    }

    public function reply(Request $request, $id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $request->validate(['body' => 'required|string']);
        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);

        (new WaSender())->send([
            'business_id' => $businessId,
            'channel_id'  => $conversation->channel_id,
            'to'          => $conversation->wa_id,
            'body'        => $request->input('body'),
            'source'      => 'agent',
            'created_by'  => auth()->id(),
        ]);

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

    /** Claim the conversation (human handoff) — pauses AI for this thread. */
    public function assign($id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        $conversation->forceFill(['assigned_user_id' => auth()->id()])->save();

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

    public function release($id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        $conversation->forceFill(['assigned_user_id' => null])->save();

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

    public function toggleAi($id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        $conversation->forceFill(['ai_enabled' => !$conversation->ai_enabled])->save();

        return response()->json(['ok' => true, 'ai' => (bool) $conversation->ai_enabled]);
    }

    public function close($id)
    {
        $this->authorizeSend();
        $businessId = request()->session()->get('user.business_id');

        $conversation = WaConversation::where('business_id', $businessId)->findOrFail($id);
        $conversation->forceFill(['status' => 'closed', 'unread_count' => 0])->save();

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

    // ----- helpers -----

    private function listQuery(int $businessId)
    {
        return WaConversation::where('business_id', $businessId)
            ->where('status', '!=', 'closed')
            ->orderByDesc('last_message_at');
    }

    private function authorizeView(): void
    {
        if (!auth()->user()->can('whatsapp.view_messages')) {
            abort(403, 'Unauthorized action.');
        }
    }

    private function authorizeSend(): void
    {
        if (!auth()->user()->can('whatsapp.send_messages')) {
            abort(403, 'Unauthorized action.');
        }
    }
}
