<?php

namespace App\Http\Controllers;

use App\Models\Ticket;
use App\Models\TicketReply;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

/**
 * Customer-facing support tickets.
 *
 * Mirrors the admin TicketController surface (index / show / store / reply)
 * but scoped to the authenticated user only — a customer can see and reply
 * to THEIR tickets, never anyone else's. The admin side at
 * App\Http\Controllers\Admin\TicketController owns the assign / close /
 * delete actions and sees every workspace.
 *
 * Why this controller exists: the platform shipped with admin-only ticket
 * routes (no customer create flow), so users had no way to file a support
 * request from inside the app. They'd email support out-of-band and the
 * admin would create the ticket manually on their behalf. This adds the
 * missing customer surface so the loop is self-serve.
 */
class SupportController extends Controller
{
    /**
     * GET /support
     * List the authenticated user's tickets, newest first.
     */
    public function index(Request $request): View
    {
        $user = Auth::user();

        $tickets = Ticket::where('user_id', $user->id)
            ->withCount('ticketReplies')
            ->orderByDesc('updated_at')
            ->paginate(20);

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

    /**
     * GET /support/create
     */
    public function create(): View
    {
        return view('support.create');
    }

    /**
     * POST /support
     * Create a new ticket on behalf of the authenticated user.
     */
    public function store(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'subject'  => ['required', 'string', 'max:255'],
            'body'     => ['required', 'string', 'max:10000'],
            'category' => ['nullable', 'string', 'max:100'],
            'priority' => ['nullable', 'string', 'in:low,normal,high,urgent'],
        ]);

        $user = Auth::user();

        $ticket = Ticket::create([
            'user_id'      => $user->id,
            'workspace_id' => $user->active_workspace_id,
            'subject'      => $data['subject'],
            'body'         => $data['body'],
            'category'     => $data['category'] ?? null,
            // Customers can't set urgent — they'd set every ticket urgent
            // and break triage. Admins can still bump it via the admin UI.
            'priority'     => in_array($data['priority'] ?? 'normal', ['low', 'normal', 'high'], true)
                ? $data['priority']
                : 'normal',
            'status'       => 'open',
        ]);

        return redirect()->route('support.show', $ticket)
            ->with('success', __('Ticket created. Our team will reply shortly.'));
    }

    /**
     * GET /support/{ticket}
     * Show a single ticket the user owns, with the reply thread.
     */
    public function show(Ticket $ticket): View
    {
        $this->authorizeOwnership($ticket);

        $ticket->load(['ticketReplies.user:id,name']);

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

    /**
     * POST /support/{ticket}/reply
     * Customer reply on their own ticket. Closed tickets are read-only —
     * forcing the customer to open a new one keeps SLA tracking sane.
     */
    public function reply(Request $request, Ticket $ticket): RedirectResponse
    {
        $this->authorizeOwnership($ticket);

        if (in_array($ticket->status, ['closed', 'resolved'], true)) {
            return back()->with('error', __('This ticket has been closed. Please open a new ticket if you need more help.'));
        }

        $data = $request->validate([
            'body' => ['required', 'string', 'max:10000'],
        ]);

        DB::transaction(function () use ($ticket, $data) {
            TicketReply::create([
                'ticket_id'      => $ticket->id,
                'user_id'        => Auth::id(),
                'body'           => $data['body'],
                'is_admin_reply' => false,
            ]);

            // Bump the ticket back to "waiting" status — the agent now has
            // a fresh customer message to respond to. updated_at refreshes
            // automatically, so the admin's "Sort by recent" puts this
            // ticket at the top of their queue.
            if ($ticket->status === 'waiting') {
                $ticket->update(['status' => 'open']);
            }
        });

        return redirect()->route('support.show', $ticket)
            ->with('success', __('Reply added.'));
    }

    /**
     * Reject any cross-tenant access. Without this, an authenticated
     * customer could open another customer's ticket simply by guessing
     * the numeric id in the URL — abort 404 (not 403) so the existence
     * of the ticket isn't leaked.
     */
    private function authorizeOwnership(Ticket $ticket): void
    {
        if ((int) $ticket->user_id !== (int) Auth::id()) {
            abort(404);
        }
    }
}
