<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Resources\TicketResource;
use App\Models\SupportTicket;
use App\Models\TicketReply;
use App\Models\User;
use App\Notifications\TicketCreatedNotification;
use App\Notifications\TicketCustomerReplyNotification;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Facades\Notification;

class CustomerTicketController extends Controller
{
    public function index(Request $request): AnonymousResourceCollection
    {
        $tickets = SupportTicket::query()
            ->where('user_id', $request->user()->id)
            ->latest('updated_at')
            ->paginate(15);

        return TicketResource::collection($tickets);
    }

    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'subject' => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'min:10', 'max:5000'],
            'priority' => ['required', 'in:low,medium,high,urgent'],
            'department' => ['required', 'in:billing,technical,sales,general'],
        ]);

        $ticket = SupportTicket::query()->create([
            'user_id' => $request->user()->id,
            'subject' => $validated['subject'],
            'status' => 'open',
            'priority' => $validated['priority'],
            'department' => $validated['department'],
            'last_reply_at' => now(),
        ]);

        TicketReply::query()->create([
            'ticket_id' => $ticket->id,
            'user_id' => $request->user()->id,
            'body' => $validated['message'],
            'is_staff_reply' => false,
        ]);

        $admins = User::query()->role('admin', 'web')->get();
        Notification::send($admins, new TicketCreatedNotification($ticket));

        $ticket->load('replies.user:id,name');

        return (new TicketResource($ticket))
            ->response()
            ->setStatusCode(201);
    }

    public function show(Request $request, SupportTicket $ticket): TicketResource|JsonResponse
    {
        if ($ticket->user_id !== $request->user()->id) {
            return response()->json(['message' => 'Forbidden.'], 403);
        }

        $ticket->load('replies.user:id,name');

        return new TicketResource($ticket);
    }

    public function reply(Request $request, SupportTicket $ticket): TicketResource|JsonResponse
    {
        if ($ticket->user_id !== $request->user()->id) {
            return response()->json(['message' => 'Forbidden.'], 403);
        }

        if ($ticket->status === 'closed') {
            return response()->json([
                'message' => 'Cannot reply to a closed ticket.',
            ], 422);
        }

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

        $reply = TicketReply::query()->create([
            'ticket_id' => $ticket->id,
            'user_id' => $request->user()->id,
            'body' => $validated['body'],
            'is_staff_reply' => false,
        ]);

        $ticket->update(['last_reply_at' => now()]);

        $admins = User::query()->role('admin', 'web')->get();
        Notification::send($admins, new TicketCustomerReplyNotification($ticket, $reply));

        $ticket->load('replies.user:id,name');

        return new TicketResource($ticket);
    }
}
