<?php

namespace App\Http\Controllers;

use App\Models\Ticket;
use App\Models\TicketReply;
use App\Services\TicketService;
use App\Http\Requests\TicketRequest;
use App\Http\Requests\TicketReplyRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class TicketController extends Controller
{
    public function __construct(
        protected TicketService $ticketService
    ) {}

    /**
     * Display a listing of tickets.
     */
    public function index(Request $request)
    {
        abort_unless(auth()->user()->can('view tickets'), 403);

        $user = auth()->user();
        $filters = $request->only(['status', 'priority', 'search', 'date_from', 'date_to', 'sort_by', 'sort_order', 'per_page']);

        if ($user->hasAnyRole(['Super Manager', 'Manager'])) {
            $tickets = $this->ticketService->getAllTickets($filters);
        } else {
            $tickets = $this->ticketService->getUserTickets($user->id, $filters);
        }

        $statistics = $this->ticketService->getStatistics();
        $categories = $this->ticketService->getCategories();

        return view('tickets.index', compact('tickets', 'statistics', 'categories'));
    }

    /**
     * Show the form for creating a new ticket.
     */
    public function create()
    {
        abort_unless(auth()->user()->can('create tickets'), 403);

        $categories = $this->ticketService->getCategories();

        return view('tickets.create', compact('categories'));
    }

    /**
     * Store a newly created ticket.
     */
    public function store(TicketRequest $request)
    {
        abort_unless(auth()->user()->can('create tickets'), 403);

        $validated = $request->validated();
        if (!auth()->user()->hasAnyRole(['Super Manager', 'Manager'])) {
            unset($validated['status']);
        }

        $ticket = $this->ticketService->createTicket(
            auth()->id(),
            $validated
        );

        return redirect()
            ->route('tickets.show', $ticket)
            ->with('success', 'Ticket created successfully! Your ticket ID is ' . $ticket->unique_identifier);
    }

    /**
     * Display the specified ticket.
     */
    public function show(Ticket $ticket)
    {
        abort_unless($this->canViewTicket($ticket), 403);

        $user = auth()->user();
        $isAdmin = $user->hasAnyRole(['Super Manager', 'Manager']);

        // Load replies — hide internal notes from non-admin users
        $ticket->load([
            'user',
            'assignee',
            'replies' => function ($query) use ($isAdmin) {
                if (!$isAdmin) {
                    $query->where('is_internal', false);
                }
            },
            'replies.user',
        ]);

        return view('tickets.show', compact('ticket'));
    }

    /**
     * Show the form for editing the specified ticket.
     */
    public function edit(Ticket $ticket)
    {
        abort_unless(auth()->user()->can('edit tickets'), 403);
        abort_unless($this->canModifyTicket($ticket), 403);

        return view('tickets.edit', compact('ticket'));
    }

    /**
     * Update the specified ticket.
     */
    public function update(TicketRequest $request, Ticket $ticket)
    {
        abort_unless(auth()->user()->can('edit tickets'), 403);
        abort_unless($this->canModifyTicket($ticket), 403);

        $validated = $request->validated();
        if (!auth()->user()->hasAnyRole(['Super Manager', 'Manager'])) {
            unset($validated['status']);
        }

        $ticket->update($validated);

        return redirect()
            ->route('tickets.show', $ticket)
            ->with('success', 'Ticket updated successfully!');
    }

    /**
     * Update ticket status.
     */
    public function updateStatus(Request $request, Ticket $ticket)
    {
        abort_unless(auth()->user()->can('edit tickets'), 403);

        $validated = $request->validate([
            'status' => 'required|in:pending,in_progress,resolved,closed',
            'notes' => 'nullable|string|max:1000',
        ]);

        $this->ticketService->updateStatus(
            $ticket,
            $validated['status'],
            auth()->id(),
            $validated['notes'] ?? null
        );

        return redirect()
            ->route('tickets.show', $ticket)
            ->with('success', 'Ticket status updated!');
    }

    /**
     * Assign ticket to an agent.
     */
    public function assign(Request $request, Ticket $ticket)
    {
        abort_unless(auth()->user()->can('assign tickets'), 403);

        $validated = $request->validate([
            'agent_id' => 'nullable|exists:users,id',
        ]);

        $this->ticketService->assignToAgent($ticket, $validated['agent_id']);

        return redirect()
            ->route('tickets.show', $ticket)
            ->with('success', 'Ticket assigned successfully!');
    }

    /**
     * Add a reply to the ticket.
     */
    public function reply(TicketReplyRequest $request, Ticket $ticket)
    {
        abort_unless($this->canViewTicket($ticket), 403);
        abort_unless(auth()->user()->can('reply tickets'), 403);

        $this->ticketService->addReply(
            $ticket,
            auth()->id(),
            $request->input('message'),
            $request->boolean('is_internal', false)
        );

        return redirect()
            ->route('tickets.show', $ticket)
            ->with('success', 'Reply added successfully!');
    }

    /**
     * Remove the specified ticket.
     */
    public function destroy(Ticket $ticket)
    {
        abort_unless(auth()->user()->can('delete tickets'), 403);
        abort_unless(auth()->user()->hasAnyRole(['Super Manager', 'Manager']), 403);

        $this->ticketService->deleteTicket($ticket);

        return redirect()
            ->route('tickets.index')
            ->with('success', 'Ticket deleted successfully!');
    }

    /**
     * Check if user can view the ticket.
     */
    protected function canViewTicket(Ticket $ticket): bool
    {
        $user = auth()->user();

        // Admins can view all tickets
        if ($user->hasAnyRole(['Super Manager', 'Manager'])) {
            return true;
        }

        // Users can view their own tickets
        return $ticket->user_id === $user->id;
    }

    /**
     * Check if user can modify the ticket.
     */
    protected function canModifyTicket(Ticket $ticket): bool
    {
        $user = auth()->user();

        // Admins can modify all tickets
        if ($user->hasAnyRole(['Super Manager', 'Manager'])) {
            return true;
        }

        // Users can modify their own open tickets
        return $ticket->user_id === $user->id && $ticket->isOpen();
    }
}
