<?php

namespace App\Http\Controllers\Api\V1\Client\Profile;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\SupportTicketRequest;
use App\Models\SupportTicket;
use App\Services\ModalIndexQuey;
use App\Traits\Formatter;
use App\Traits\MediaUploader;
use Illuminate\Http\Request;

class SupportTicketController extends Controller
{
    use Formatter, MediaUploader;

    /**
     * @OA\Get(
     *     path="/api/v1/profile/support-tickets",
     *     summary="Get a list of support tickets for the user",
     *     description="Returns a list of support tickets associated with the authenticated user.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\Response(
     *         response=200,
     *         description="Successfully fetched the support tickets",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="data", type="array",
     *
     *                 @OA\Items(
     *                     type="object",
     *
     *                     @OA\Property(property="id", type="integer", example=1),
     *                     @OA\Property(property="title", type="string", example="Support Ticket #1"),
     *                     @OA\Property(property="status", type="string", example="open"),
     *                     @OA\Property(property="created_at", type="string", format="date-time", example="2024-11-17T14:25:00Z"),
     *                     @OA\Property(property="updated_at", type="string", format="date-time", example="2024-11-17T14:30:00Z")
     *                 )
     *             )
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Internal server error")
     *         )
     *     )
     * )
     */
    public function index()
    {
        /**
         * @val \App\Models\User $user
         */
        $user = auth('client')->user();

        $tickets = ModalIndexQuey::get($user->supportTickets());

        return $this->withSuccess($tickets);
    }

    /**
     * @OA\Post(
     *     path="/api/v1/profile/support-tickets",
     *     summary="Create a new support ticket for the user",
     *     description="Allows a user to create a new support ticket and attach any optional files.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\RequestBody(
     *         required=true,
     *
     *         @OA\JsonContent(
     *             required={"subject", "description"},
     *
     *             @OA\Property(property="subject", type="string", example="Technical Issue", description="The subject or title of the support ticket."),
     *             @OA\Property(property="description", type="string", example="Details of the issue.", description="Detailed description of the issue."),
     *             @OA\Property(property="attachments", type="array", @OA\Items(type="string", format="binary"), description="Optional attachments for the ticket (files).")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=200,
     *         description="Support ticket created successfully",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Support ticket created successfully")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=400,
     *         description="Bad request, validation errors",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Validation errors occurred"),
     *             @OA\Property(property="errors", type="object", additionalProperties={"type": "array", "items": {"type": "string"}})
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Internal server error")
     *         )
     *     )
     * )
     */
    public function store(SupportTicketRequest $request)
    {
        /**
         * @var \App\Models\User $user
         */
        $user = $request->user('client');

        $support = $user->supportTickets()->create([
            ...$request->validated(),
        ]);

        if (isset($request->attachments)) {
            $attachments = collect($request->attachments)->map(function ($attachment) {
                return $this->upload($attachment, 'support-tickets');
            })->toArray();
            $support->update(['attachments' => $attachments]);
        }

        return $this->withSuccess(__('Support ticket created successfully'));
    }

    /**
     * @OA\Get(
     *     path="/api/v1/profile/support-tickets/{id}",
     *     summary="Get details of a specific support ticket",
     *     description="Returns the details of a support ticket, including its replies and the user who made the reply.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\Parameter(
     *         name="id",
     *         in="path",
     *         required=true,
     *         description="The ID of the support ticket",
     *
     *         @OA\Schema(type="integer", example=1)
     *     ),
     *
     *     @OA\Response(
     *         response=200,
     *         description="Successfully fetched support ticket details",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="data",
     *                 type="object",
     *                 @OA\Property(property="id", type="integer", example=1),
     *                 @OA\Property(property="subject", type="string", example="Issue with deposit"),
     *                 @OA\Property(property="status", type="string", example="open"),
     *                 @OA\Property(property="created_at", type="string", format="date-time", example="2024-11-17T10:30:00Z"),
     *                 @OA\Property(property="updated_at", type="string", format="date-time", example="2024-11-17T11:00:00Z"),
     *                 @OA\Property(property="replies", type="array",
     *
     *                     @OA\Items(
     *                         type="object",
     *
     *                         @OA\Property(property="id", type="integer", example=1),
     *                         @OA\Property(property="message", type="string", example="I am unable to deposit."),
     *                         @OA\Property(property="created_at", type="string", format="date-time", example="2024-11-17T11:15:00Z"),
     *                         @OA\Property(property="user", type="object",
     *                             @OA\Property(property="id", type="integer", example=2),
     *                             @OA\Property(property="first_name", type="string", example="John"),
     *                             @OA\Property(property="last_name", type="string", example="Doe"),
     *                             @OA\Property(property="avatar", type="string", example="https://example.com/avatar.jpg")
     *                         )
     *                     )
     *                 )
     *             )
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=404,
     *         description="Support ticket not found",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Support ticket not found.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Internal server error")
     *         )
     *     )
     * )
     */
    public function show(SupportTicket $supportTicket)
    {
        return $this->withSuccess($supportTicket->load(['replies' => fn ($q) => $q->with('reply:id,first_name,last_name,avatar')]));
    }

    /**
     * @OA\Put(
     *     path="/api/v1/profile/support-tickets/{id}",
     *     summary="Update a support ticket",
     *     description="Updates an existing support ticket. You can modify ticket details and attachments.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\Parameter(
     *         name="id",
     *         in="path",
     *         required=true,
     *         description="The ID of the support ticket to be updated",
     *
     *         @OA\Schema(type="integer", example=1)
     *     ),
     *
     *     @OA\RequestBody(
     *         required=true,
     *
     *         @OA\JsonContent(
     *             required={"subject", "message"},
     *
     *             @OA\Property(property="subject", type="string", example="Issue with deposit"),
     *             @OA\Property(property="message", type="string", example="I cannot deposit funds, please assist."),
     *             @OA\Property(property="attachments", type="array", @OA\Items(type="string", format="uri", example="https://example.com/attachment.jpg")),
     *             @OA\Property(property="status", type="string", example="open")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=200,
     *         description="Successfully updated the support ticket",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Support ticket updated successfully")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=400,
     *         description="Bad Request, validation errors",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Invalid data provided")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=404,
     *         description="Support ticket not found",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Support ticket not found")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Something went wrong")
     *         )
     *     )
     * )
     */
    public function update(SupportTicketRequest $request, SupportTicket $supportTicket)
    {
        try {
            $supportTicket->update($request->validated());

            if (isset($request->attachments)) {
                foreach ($supportTicket->attachments as $attachment) {
                    $this->delete($attachment);
                }
                $attachments = collect($request->attachments)->map(function ($attachment) {
                    return $this->upload($attachment, 'support-tickets');
                })->toArray();

                $supportTicket->update(['attachments' => $attachments]);
            }

        } catch (\Throwable $th) {
            return $this->withError($th->getMessage());
        }

        return $this->withSuccess(__('Support ticket updated successfully'));
    }

    /**
     * @OA\Delete(
     *     path="/api/v1/profile/support-tickets/{ticket_no}",
     *     summary="Delete a support ticket and its attachments",
     *     description="Allows a user to delete a support ticket along with any attached files.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\Parameter(
     *         name="ticket_no",
     *         in="path",
     *         required=true,
     *         description="The unique ticket number of the support ticket to delete",
     *
     *         @OA\Schema(type="string")
     *     ),
     *
     *     @OA\Response(
     *         response=200,
     *         description="Support ticket deleted successfully",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Support ticket deleted successfully")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=400,
     *         description="Bad request, invalid ticket number",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Invalid ticket number")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Something went wrong")
     *         )
     *     )
     * )
     */
    public function destroy(SupportTicket $supportTicket)
    {
        try {
            if ($supportTicket->attachments) {
                foreach ($supportTicket->attachments as $attachment) {
                    $this->delete($attachment);
                }
            }
            $supportTicket->delete();

        } catch (\Throwable $th) {
            return $this->withError($th->getMessage());
        }

        return $this->withSuccess(__('Support ticket deleted successfully'));
    }

    /**
     * @OA\Post(
     *     path="/api/v1/profile/reply-to-support-ticket/{supportTicket}",
     *     summary="Reply to a support ticket",
     *     description="Allows the user to reply to an existing support ticket with a message and optional attachments.",
     *     tags={"Support Tickets"},
     *     security={{"bearer": {}}},
     *
     *     @OA\Parameter(
     *         name="ticket_no",
     *         in="path",
     *         required=true,
     *         description="The unique ticket number of the support ticket to reply to",
     *
     *         @OA\Schema(type="string")
     *     ),
     *
     *     @OA\RequestBody(
     *         required=true,
     *
     *         @OA\MediaType(
     *             mediaType="application/json",
     *
     *             @OA\Schema(
     *                 type="object",
     *                 required={"message"},
     *
     *                 @OA\Property(property="message", type="string", maxLength=1000, example="Please provide more details about the issue."),
     *                 @OA\Property(property="attachments", type="array",
     *
     *                     @OA\Items(type="string", format="binary")
     *                 )
     *             )
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=200,
     *         description="Reply created successfully",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Reply created successfully")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=400,
     *         description="Bad request, validation failed",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Validation failed.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=401,
     *         description="Unauthorized, invalid authentication",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Unauthenticated.")
     *         )
     *     ),
     *
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error",
     *
     *         @OA\JsonContent(
     *
     *             @OA\Property(property="statusCode", type="number", example=200),
     *             @OA\Property(property="message", type="string", example="Something went wrong")
     *         )
     *     )
     * )
     */
    public function reply(Request $request, SupportTicket $supportTicket)
    {
        $request->validate([
            'message' => 'required|string|max:1000',
            'attachments' => 'nullable|array',
            'attachments.*' => 'nullable|file|mimes:jpeg,png,jpg,gif,pdf,doc,docx|max:2048',
        ]);

        /**
         * @var \App\Models\User $user
         */
        $user = $request->user('client');
        $reply = $supportTicket->replies()->create([
            'message' => $request->message,
            'reply_type' => get_class($user),
            'reply_id' => $user->id,
        ]);

        if (isset($request->attachments)) {
            $attachments = collect($request->attachments)->map(function ($attachment) {
                return $this->upload($attachment, 'support-tickets');
            })->toArray();
            $reply->update(['attachments' => $attachments]);

        }

        return $this->withSuccess(__('Reply created successfully'));
    }
}
