<?php

namespace Mtc\Plugins\MembersMessaging\Http\Controllers;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Mtc\Core\AdminUser;
use Mtc\Core\Permissions;
use Mtc\Plugins\MembersMessaging\Models\Template;
use Mtc\Plugins\MembersMessaging\Http\Resources\ThreadResource;
use Mtc\Plugins\MembersMessaging\Models\Thread;
use Mtc\Shop\Order;
use Mtc\Plugins\MembersMessaging\Models\Message;
use Mtc\Modules\Members\Models\Member;

/**
 * Controller for "Admin-side" Threads.
 */
class AdminThreadController extends Controller
{

    public function index()
    {
        return app('twig')->render('membersmessaging/admin/threads.twig');
    }

    public function createThread(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'member' => 'required|integer',
            'category' => 'required|integer'
        ]);

        $admin_id = AdminUser::getCurrent()->id;

        $thread = Thread::create([
            'title' => $validated['title'],
            'url' => str_replace('.', '-', uniqid('cp_', true)),
            'category' => $validated['category'],
            'member_id' => $validated['member'],
            'admin_id' => $admin_id,
            'status' => 1
        ]);

        return redirect()->route('admin.messaging.view_thread', ['url' => $thread->url]);
    }

    public function fetch(Request $request)
    {
        $threads = Thread::with('messages');

        if (AdminUser::getCurrent()->role && !Permissions::can(Permissions::VIEW_ALL_THREADS)) {
            $threads = $threads
                ->forAdminRole()
                ->forCurrentAdmin();

            $members = Thread::forCurrentAdmin()
                ->with('member')
                ->get()
                ->pluck('member')
                ->unique('id')
                ->values();
        }

        $admins = AdminUser::where('id', '!=', MTCADMIN_USERID)
            ->get();

        if (!isset($members)) {
            $members = Member::all();
        }

        $threads = $threads->byPriority();

        $threads = $threads->paginate(10);

        return response()->json([
            'success' => true,
            'threads' => ThreadResource::collection($threads),
            'members' => $members,
            'admins' => $admins,
            'filters' => Thread::THREAD_STATUSES,
            'categories' => Thread::THREAD_CATEGORIES,
            'message' => 'Fetched all available Threads.',
            'current_page' => $threads->currentPage(),
            'last_page' => $threads->lastPage(),
            'canViewAllThreads' => Permissions::can(Permissions::VIEW_ALL_THREADS),
        ]);
    }

    public function show($url): string
    {
        $thread = Thread::withMessagesForUrl($url)
            ->withParticipants()
            ->with('member.orders')
            ->first();

        if (!$thread) {
            return redirect()->back()->with('error', 'Thread not found');
        }

        Message::where('thread_id', $thread->id)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);

        $templates = Template::all();

        $admins = AdminUser::where('id', '!=', MTCADMIN_USERID)->get();

        return app('twig')->render('membersmessaging/admin/messages.twig', [
            'admins' => $admins,
            'thread' => $thread,
            'templates' => $templates,
        ]);
    }

    public function archive(Request $request)
    {
        $ids = $request->input('threads', []);

        if (!$ids) {
            return response()->json([
                'success' => false,
                'message' => 'There were no selected Threads'
            ], 400);
        }

        Thread::whereIn('id', $ids)->update(['status' => 4]);
        Thread::whereIn('id', $ids)->delete();

        $count = count($ids);

        return response()->json([
            'success' => true,
            'threads' => ThreadResource::collection(Thread::all()),
            'message' => "Successfully deleted $count threads."
        ], 200);
    }

    public function delete(Request $request)
    {
        $ids = $request->input('threads', []);

        if (!$ids) {
            return response()->json([
                'success' => false,
                'message' => 'There were no selected Threads'
            ], 400);
        }

        $count = Thread::withTrashed()
            ->whereIn('id', $ids)
            ->forceDelete();

        return response()->json([
            'success' => true,
            'threads' => ThreadResource::collection(Thread::all()),
            'message' => "Successfully delete $count threads permanently."
        ]);
    }

    public function star(Request $request)
    {
        $ids = $request->input('threads', []);

        if (!$ids) {
            return response()->json([
                'success' => false,
                'message' => 'There were no selected Threads'
            ], 400);
        }

        $count = Thread::whereIn('id', $ids)
            ->update(['status' => 3]);

        return response()->json([
            'success' => true,
            'message' => "Successfully marked $count as starred."
        ], 200);
    }


    public function markOpen(Request $request)
    {
        $ids = $request->input('threads', []);

        if (!$ids) {
            return response()->json([
                'success' => false,
                'message' => 'There were no selected Threads'
            ], 400);
        }

        $count = Thread::whereIn('id', $ids)
            ->update(['status' => 1]);

        return response()->json([
            'success' => true,
            'message' => "Successfully marked $count threads as open."
        ], 200);
    }

    public function markClosed(Request $request)
    {
        $ids = $request->input('threads', []);

        if (!$ids) {
            return response()->json([
                'success' => false,
                'message' => 'There were no selected Threads'
            ], 400);
        }

        $count = Thread::whereIn('id', $ids)
            ->update(['status' => 2]);

        return response()->json([
            'success' => true,
            'message' => "Successfully marked $count threads as closed."
        ], 200);
    }

    public function filter(Request $request)
    {
        $filter = $request->input('filter');

        if ($filter === null || $filter === '') {
            return response()->json([
                'success' => false,
                'threads' => [],
                'message' => 'No filter selected.'
            ]);
        }

        $threads = Thread::with('latestMessage');

        if (!Permissions::can(Permissions::VIEW_ALL_THREADS)) {
            $threads = $threads
                ->forAdminRole()
                ->forCurrentAdmin();
        }

        if ($filter == 0) { // All threads

            $threads = $threads->get();
            $message = "Showing all threads.";
        } else if ($filter == 4) { // Archived
            $threads = $threads->withTrashed()
                ->where('status', 4) // Archived status
                ->get();
            $message = "Showing " . $threads->count() . " archived threads.";
        } else {
            $threads = $threads
                ->where('status', $filter) // adjust for array numbering if needed
                ->get();
            $message = "Showing " . $threads->count() . " threads with status {$filter}.";
        }

        return response()->json([
            'success' => true,
            'threads' => ThreadResource::collection($threads),
            'message' => $message,
        ]);
    }

    public function restore(Request $request)
    {
        try {
            $ids = $request->input('threads', []);

            if (!$ids) {
                return response()->json([
                    'success' => false,
                    'message' => 'There were no selected Threads'
                ], 400);
            }

            Thread::onlyTrashed()
                ->whereIn('id', $ids)
                ->restore();

            Thread::withTrashed()
                ->whereIn('id', $ids)
                ->update(['status' => 1]);

            return response()->json([
                'success' => true,
                'message' => 'Threads have been restored.'
            ]);
        } catch (Exception) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to restore threads. Please try again.'
            ], 400);
        }
    }

    /**
     *
     * Function for 'manage.order.php' that creates a new thread regarding an order
     *
     * @param Request $request
     * @param Order $order
     *
     * @return Illuminate\Http\RedirectResponse
     **/
    public function messageForOrder(Order $order)
    {

        $adminId  = AdminUser::getCurrent()->id;
        $memberId = $order->member_id ?? $order->member ?? null;

        $title = "RE: Your recent order, Order ID: " . $order->id;

        $thread = Thread::firstOrNew([
            'admin_id' => $adminId,
            'member_id' => $memberId,
            'order_id' => $order->id,
            'title' => $title,
            'category' => 2,
            'status' => 1,
        ]);

        // If the entry is blank, fill it with a unique URL
        if (blank($thread->url)) {
            $thread->url = str_replace('.', '-', uniqid('cp_', true));
            $thread->save();
        }

        return redirect()->route('admin.messaging.view_thread', ['url' => $thread->url]);
    }
}
