<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Ticket;
use App\Models\TicketCategory;
use App\Models\TicketMessage;
use App\Models\User;
use App\Notifications\Ticket\AdminResponseNotification;
use App\Notifications\Ticket\TicketClosureNotification;
use App\Notifications\Ticket\TicketCreatedNotification;
use App\Notifications\Ticket\TicketStatusUpdateNotification;
use Illuminate\Http\Request;

class AdminTicketController extends Controller
{
    protected array $data = [];

    public function index()
    {
        $this->data['title'] = 'Tickets';

        $query = Ticket::with('category', 'user')->orderBy('created_at', 'desc');

        if (request()->filled('category_id')) {
            $query->where('category_id', request('category_id'));
        }

        if (request()->filled('user_id')) {
            $query->where('user_id', request('user_id'));
        }

        if (request()->filled('priority')) {
            $query->where('priority', request('priority'));
        }

        if (request()->filled('status')) {
            $query->where('status', request('status'));
        }

        if (request('search')) {
            $query->where(function ($query) {
                $query->where('subject', 'like', '%' . request('search') . '%');
            });
        }

        $this->data['tickets'] = $query->paginate(10);
        $this->data['ticketCategories'] = TicketCategory::has('tickets')->get();
        $this->data['users'] = User::has('tickets')->get();

        return view('admin.helpdesk.ticket.index', $this->data);
    }

    public function create()
    {
        $this->data['title'] = 'Create Ticket';
        $this->data['ticketCategories'] = TicketCategory::all();
        $this->data['users'] = User::all();
        return view('admin.helpdesk.ticket.create', $this->data);
    }

    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'subject' => 'required|string|max:255',
            'message_content' => 'required',
            'user_id' => 'required|exists:users,id',
            'priority' => 'required|in:Low,Medium,High,Critical',
            'category_id' => 'required|exists:ticket_categories,id',
        ]);

        $ticket = Ticket::create([
            'subject' => $validatedData['subject'],
            'user_id' => $validatedData['user_id'],
            'priority' => $validatedData['priority'],
            'category_id' => $validatedData['category_id'],
        ]);

        $ticket->messages()->create([
            'user_id' => auth()->id(),
            'message_content' => $validatedData['message_content'],
        ]);

        $ticket->user->notify(new TicketCreatedNotification($ticket));

        return redirect()->route('ch-admin.ticket.show', $ticket->id)->with('success', 'Ticket created successfully!');
    }

    public function show($id)
    {
        $this->data['ticket'] = Ticket::with(['user', 'category', 'messages', 'messages.media'])->findOrFail($id);

        $this->data['ticketCategories'] = TicketCategory::all();

        $this->data['messages'] = $this->data['ticket']->messages()->orderBy('created_at', 'desc')->get();

        $this->data['title'] = "Ticket: [{$this->data['ticket']->reference_id}]";

        return view('admin.helpdesk.ticket.show', $this->data);
    }

    public function update(Request $request, $id)
    {
        $validatedData = $request->validate([
            'status' => 'required|in:Open,In Progress,Resolved,Closed',
            'priority' => 'required|in:Low,Medium,High,Critical',
            'category_id' => 'required|exists:ticket_categories,id',
        ]);

        $ticket = Ticket::findOrFail($id);
        $originalStatus = $ticket->status;

        $ticket->update([
            'status' => $validatedData['status'],
            'priority' => $validatedData['priority'],
            'category_id' => $validatedData['category_id'],
        ]);

        if ($originalStatus !== $ticket->status) {
            if (in_array($ticket->status, ['Resolved', 'Closed'])) {
                $ticket->user->notify(new TicketClosureNotification($ticket));
            } else {
                $ticket->user->notify(new TicketStatusUpdateNotification($ticket));
            }
        }

        return redirect()->back()->with('success', 'Ticket updated successfully!');
    }

    public function editMessage($id)
    {
        $message = TicketMessage::with('media')->findOrFail($id);

        $media = $message->getMedia('attachments')->map(function ($media) {
            return [
                'id' => $media->id,
                'name' => $media->filename . '.' . $media->extension,
                'image_url' => $media->getUrl('thumbnail'),
                'size' => $media->size,
            ];
        });

        return response()->json([
            'message_content' => $message->message_content,
            'media' => $media
            ]);
    }

    public function storeMessage(Request $request, $ticketId)
    {
        $validatedData = $request->validate([
            'message_content' => 'required|string'
        ]);

        $ticket = Ticket::findOrFail($ticketId);

        $ticket->update([
            'status' => 'Open',
            'updated_at' => now(),
        ]);

        $message = $ticket->messages()->create([
            'user_id' => auth()->id(),
            'message_content' => $validatedData['message_content'],
        ]);

        if (\request()->has('attachments') && sizeof(\request()->input('attachments')) > 0) {
            $message->syncMedia(\request()->input('attachments'), 'attachments');
        }

        $ticket->user->notify(new AdminResponseNotification($message));

        return redirect()->back()->with('success', 'Message sent successfully!');
    }

    public function updateMessage(Request $request, $id)
    {
        $validatedData = $request->validate([
            'message_content' => 'required|string',
        ]);

        $ticketMessage = TicketMessage::findOrFail($id);

        $ticketMessage->update(['message_content' => $validatedData['message_content']]);

        if (\request()->has('attachments') && sizeof(\request()->input('attachments')) > 0) {
            $ticketMessage->syncMedia(\request()->input('attachments'), 'attachments');
        }

        return redirect()->back()->with('success', 'Message updated successfully!');
    }

    public function deleteMessage($id)
    {
        $message = TicketMessage::findOrFail($id);
        $message->delete();

        return redirect()->back()->with('success', 'Message deleted successfully!');
    }

    public function destroy(Request $request)
    {
        $ticket = Ticket::findOrFail($request->ticket_id);

        $ticket->messages()->delete();

        $ticket->delete();

        return redirect()->route('ch-admin.ticket.index')->with('success', 'Ticket deleted successfully.');
    }

    public function bulkDestroy(Request $request)
    {
        $validatedData = $request->validate([
            'tickets' => 'required|array|min:1',
            'tickets.*' => 'exists:tickets,id',
        ]);

        $tickets = Ticket::whereIn('id', $validatedData['tickets'])->get();

        foreach ($tickets as $ticket) {
            $ticket->messages()->delete();
            $ticket->delete();
        }

        session()->flash('success', 'Selected Tickets deleted successfully!');

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