<?php

namespace App\Http\Controllers\Api\V1;

use App\CentralLogics\Helpers;
use App\Http\Controllers\Controller;
use App\Models\ChatLog;
use App\Services\AiChat\AiChatService;
use App\Services\AiChat\AiProductIndexService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;

class AiChatController extends Controller
{
    public function __construct(
        private readonly AiChatService $aiChatService,
        private readonly AiProductIndexService $aiProductIndexService
    )
    {
    }

    public function message(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'message' => 'required|string|max:2000',
            'session_id' => 'nullable|string|max:120',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => Helpers::error_processor($validator)], 422);
        }

        $data = $this->aiChatService->handleApiMessage(
            (string) $request->message,
            $request->user(),
            $request->input('session_id')
        );

        return response()->json([
            'message' => 'success',
            'data' => $data,
        ]);
    }

    public function imageSearch(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'image' => 'required|image|max:5120',
            'message' => 'nullable|string|max:2000',
            'session_id' => 'nullable|string|max:120',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => Helpers::error_processor($validator)], 422);
        }

        $data = $this->aiChatService->handleApiImageSearch(
            $request->file('image'),
            $request->input('message'),
            $request->user(),
            $request->input('session_id')
        );

        return response()->json([
            'message' => 'success',
            'data' => $data,
        ]);
    }

    public function syncProducts(Request $request): JsonResponse
    {
        if (!$this->canManageAiChat($request)) {
            return response()->json(['message' => 'forbidden'], 403);
        }

        $synced = $this->aiProductIndexService->syncAllProducts($request->integer('limit') ?: null);

        return response()->json([
            'message' => 'success',
            'data' => [
                'synced_products' => $synced,
            ],
        ]);
    }

    public function syncPages(Request $request): JsonResponse
    {
        if (!$this->canManageAiChat($request)) {
            return response()->json(['message' => 'forbidden'], 403);
        }

        $synced = $this->aiProductIndexService->syncPolicyPages();

        return response()->json([
            'message' => 'success',
            'data' => [
                'synced_pages' => $synced,
            ],
        ]);
    }

    public function sessions(Request $request): JsonResponse
    {
        if (!$this->canManageAiChat($request)) {
            return response()->json(['message' => 'forbidden'], 403);
        }

        if (!Schema::hasTable('chat_logs') || !Schema::hasColumn('chat_logs', 'session_id')) {
            return response()->json(['message' => 'success', 'data' => []]);
        }

        $sessions = ChatLog::query()
            ->select([
                'session_id',
                DB::raw('MAX(customer_id) as customer_id'),
                DB::raw('COUNT(*) as messages_count'),
                DB::raw('MAX(created_at) as last_message_at'),
            ])
            ->whereNotNull('session_id')
            ->groupBy('session_id')
            ->orderByDesc('last_message_at')
            ->paginate((int) ($request->input('limit', 20)));

        return response()->json([
            'message' => 'success',
            'data' => $sessions,
        ]);
    }

    public function logs(Request $request): JsonResponse
    {
        if (!$this->canManageAiChat($request)) {
            return response()->json(['message' => 'forbidden'], 403);
        }

        if (!Schema::hasTable('chat_logs')) {
            return response()->json(['message' => 'success', 'data' => []]);
        }

        $logs = ChatLog::query()
            ->when($request->filled('session_id') && Schema::hasColumn('chat_logs', 'session_id'), fn ($query) => $query->where('session_id', $request->input('session_id')))
            ->latest('created_at')
            ->paginate((int) ($request->input('limit', 20)));

        return response()->json([
            'message' => 'success',
            'data' => $logs,
        ]);
    }

    public function feedback(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'log_id' => 'required|integer',
            'feedback_note' => 'nullable|string|max:2000',
            'is_wrong_answer_reported' => 'nullable|boolean',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => Helpers::error_processor($validator)], 422);
        }

        if (!Schema::hasTable('chat_logs')) {
            return response()->json(['message' => 'not_found'], 404);
        }

        $log = ChatLog::query()->find($request->integer('log_id'));
        if (!$log) {
            return response()->json(['message' => 'not_found'], 404);
        }

        $update = [];
        if (Schema::hasColumn('chat_logs', 'is_wrong_answer_reported')) {
            $update['is_wrong_answer_reported'] = $request->boolean('is_wrong_answer_reported', true);
        }
        if (Schema::hasColumn('chat_logs', 'feedback_note')) {
            $update['feedback_note'] = $request->input('feedback_note');
        }

        if (!empty($update)) {
            $log->update($update);
        }

        return response()->json([
            'message' => 'success',
            'data' => $log->fresh(),
        ]);
    }

    public function send(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'message' => 'required_without:image|string|max:2000',
            'conversation_id' => 'nullable|integer',
            'order_id' => 'nullable|integer',
            'image.*' => 'nullable|image|max:5120',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => Helpers::error_processor($validator)], 422);
        }

        $request->merge([
            'receiver_type' => 'admin',
        ]);

        return app(ConversationController::class)->messages_store($request);
    }

    public function reply(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'message' => 'required|string|max:2000',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => Helpers::error_processor($validator)], 422);
        }

        $replyData = $this->aiChatService->previewReply($request->message, $request->user());

        return response()->json([
            'message' => 'success',
            'data' => $replyData,
        ]);
    }

    public function productSearch(Request $request): JsonResponse
    {
        $query = trim($request->get('q', ''));
        if (empty($query)) {
            return response()->json(['message' => 'success', 'data' => []]);
        }
        $products = $this->aiChatService->searchProducts($query, 5);
        return response()->json(['message' => 'success', 'data' => $products]);
    }

    protected function canManageAiChat(Request $request): bool
    {
        if (auth('admin')->check()) {
            return true;
        }

        $configuredToken = (string) env('AI_CHAT_SYNC_TOKEN', '');
        if ($configuredToken === '') {
            return false;
        }

        $requestToken = (string) ($request->bearerToken() ?: $request->header('X-AI-CHAT-TOKEN', ''));

        return $requestToken !== '' && hash_equals($configuredToken, $requestToken);
    }
}
