<?php

namespace App\Http\Controllers\Api\Messaging;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Whatsapp\WhatsappInviteSendRequest;
use App\Http\Requests\Whatsapp\WhatsappLinkIndexRequest;
use App\Http\Requests\Whatsapp\WhatsappLinkStoreRequest;
use App\Http\Requests\Whatsapp\WhatsappLinkUpdateRequest;
use App\Http\Requests\Whatsapp\WhatsappMembershipUpdateRequest;
use App\Http\Requests\Whatsapp\WhatsappParentContactsByClassRequest;
use App\Http\Requests\Whatsapp\WhatsappParentContactsRequest;
use App\Http\Resources\Whatsapp\WhatsappClassSectionContactResource;
use App\Http\Resources\Whatsapp\WhatsappGroupLinkCollection;
use App\Http\Resources\Whatsapp\WhatsappGroupLinkResource;
use App\Http\Resources\Whatsapp\WhatsappParentContactResource;
use App\Services\Whatsapp\WhatsappContactService;
use App\Services\Whatsapp\WhatsappContextService;
use App\Services\Whatsapp\WhatsappInviteService;
use App\Services\Whatsapp\WhatsappLinkService;
use App\Services\Whatsapp\WhatsappMembershipService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class WhatsappController extends BaseApiController
{
    public function __construct(
        private WhatsappLinkService $linkService,
        private WhatsappContactService $contactService,
        private WhatsappInviteService $inviteService,
        private WhatsappMembershipService $membershipService,
        private WhatsappContextService $context
    ) {
        parent::__construct();
    }

    public function index(WhatsappLinkIndexRequest $request): JsonResponse
    {
        $links = $this->linkService->paginate($request->validated());
        $collection = new WhatsappGroupLinkCollection($links);

        return $this->success([
            'links' => $collection->toArray($request),
            'meta' => $collection->with($request)['meta'],
        ]);
    }

    public function show(int $linkId): JsonResponse
    {
        $link = $this->linkService->findOrFail($linkId);

        return $this->success([
            'link' => new WhatsappGroupLinkResource($link),
        ]);
    }

    public function store(WhatsappLinkStoreRequest $request): JsonResponse
    {
        $link = $this->linkService->upsert($request->validated());

        $code = $link->wasRecentlyCreated ? Response::HTTP_CREATED : Response::HTTP_OK;

        return $this->success([
            'link' => new WhatsappGroupLinkResource($link),
        ], 'WhatsApp group link saved.', $code);
    }

    public function update(WhatsappLinkUpdateRequest $request, int $linkId): JsonResponse
    {
        $link = $this->linkService->update($linkId, $request->validated());

        return $this->success([
            'link' => new WhatsappGroupLinkResource($link),
        ], 'WhatsApp group link updated.');
    }

    public function destroy(int $linkId): JsonResponse
    {
        $this->linkService->delete($linkId);

        return $this->success(null, 'WhatsApp group link deleted.');
    }

    public function parentContacts(WhatsappParentContactsRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $schoolYear = $this->context->schoolYear($payload['school_year'] ?? null);
        $semester = array_key_exists('semester', $payload)
            ? (string) ($payload['semester'] ?? '')
            : $this->context->semester();

        $contacts = $this->contactService->listParentContacts($schoolYear, $semester);

        return $this->success([
            'contacts' => WhatsappParentContactResource::collection($contacts),
        ]);
    }

    public function parentContactsByClass(WhatsappParentContactsByClassRequest $request): JsonResponse
    {
        $payload = $request->validated();
        $schoolYear = $this->context->schoolYear($payload['school_year'] ?? null);
        $semester = array_key_exists('semester', $payload)
            ? (string) ($payload['semester'] ?? '')
            : $this->context->semester();

        $sections = $this->contactService->listParentContactsByClass($schoolYear, $semester);

        return $this->success([
            'class_sections' => WhatsappClassSectionContactResource::collection($sections),
        ]);
    }

    public function sendInvites(WhatsappInviteSendRequest $request): JsonResponse
    {
        try {
            $result = $this->inviteService->send($request->validated());
        } catch (\Throwable $e) {
            Log::error('WhatsApp invite send failed: ' . $e->getMessage());
            return $this->error('Invite processing failed.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        if (!($result['ok'] ?? false)) {
            return $this->error($result['message'] ?? 'Invite processing failed.', Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        return $this->success([
            'triggered' => (int) ($result['triggered'] ?? 0),
        ], 'Invite processing started.');
    }

    public function updateMembership(WhatsappMembershipUpdateRequest $request): JsonResponse
    {
        $userId = $this->authenticatedUserIdOrUnauthorized();
        if ($userId instanceof JsonResponse) {
            return $userId;
        }

        try {
            $result = $this->membershipService->updateMembership($request->validated(), $userId);
        } catch (\Throwable $e) {
            Log::error('WhatsApp membership update failed: ' . $e->getMessage());
            return $this->error('Failed to save membership.', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        if (!($result['ok'] ?? false)) {
            $code = str_contains((string) ($result['message'] ?? ''), 'missing')
                ? Response::HTTP_INTERNAL_SERVER_ERROR
                : Response::HTTP_UNPROCESSABLE_ENTITY;

            return $this->error($result['message'] ?? 'Failed to save membership.', $code);
        }

        return $this->success([
            'saved' => $result['saved'] ?? [],
            'term' => $result['term'] ?? [],
        ], 'Membership saved.');
    }

    /**
     * @return int|JsonResponse
     */
    private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
        }

        return $userId;
    }
}
