<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\UserKeyword;
use App\Services\Auth\ApiKeyService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class UserKeywordController extends Controller
{
    public function __construct(
        private readonly ApiKeyService $keys
    ) {
    }

    private function ensureUser(Request $request): ?array
    {
        $user = $this->keys->resolveUser($request);
        if (!$user) {
            return ['error' => 'unauthorized', 'status' => 401];
        }

        return ['user' => $user];
    }

    public function index(Request $request): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $user = $check['user'];
        $items = UserKeyword::where('user_id', $user->id)
            ->orderByDesc('id')
            ->get(['id', 'emoji_slug', 'keyword', 'lang', 'created_at', 'updated_at']);

        return response()->json(['ok' => true, 'items' => $items]);
    }

    public function store(Request $request): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $data = $request->validate([
            'emoji_slug' => 'required|string|max:120',
            'keyword' => 'required|string|max:200',
            'lang' => 'nullable|string|max:10',
        ]);

        $lang = $data['lang'] ?? 'und';
        $user = $check['user'];
        $limit = $this->keywordLimitFor($user);
        if ($limit !== null) {
            $exists = UserKeyword::where('user_id', $user->id)
                ->where('emoji_slug', $data['emoji_slug'])
                ->where('keyword', $data['keyword'])
                ->exists();
            if (!$exists) {
                $count = UserKeyword::where('user_id', $user->id)->count();
                if ($count >= $limit) {
                    return response()->json(['ok' => false, 'error' => 'free_limit_reached', 'limit' => $limit], 403);
                }
            }
        }

        $item = UserKeyword::updateOrCreate(
            [
                'user_id' => $user->id,
                'emoji_slug' => $data['emoji_slug'],
                'keyword' => $data['keyword'],
            ],
            [
                'lang' => $lang,
            ]
        );

        return response()->json(['ok' => true, 'item' => $item]);
    }

    public function destroy(Request $request, int $id): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $deleted = UserKeyword::where('user_id', $check['user']->id)
            ->where('id', $id)
            ->delete();

        return response()->json(['ok' => true, 'deleted' => $deleted > 0]);
    }

    public function update(Request $request, int $id): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $data = $request->validate([
            'emoji_slug' => 'required|string|max:120',
            'keyword' => 'required|string|max:200',
            'lang' => 'nullable|string|max:10',
        ]);

        $item = UserKeyword::where('user_id', $check['user']->id)
            ->where('id', $id)
            ->first();

        if (!$item) {
            return response()->json(['ok' => false, 'error' => 'not_found'], 404);
        }

        $duplicate = UserKeyword::where('user_id', $check['user']->id)
            ->where('emoji_slug', $data['emoji_slug'])
            ->where('keyword', $data['keyword'])
            ->first();

        if ($duplicate && $duplicate->id !== $item->id) {
            $item->delete();
            $item = $duplicate;
        } else {
            $item->update([
                'emoji_slug' => $data['emoji_slug'],
                'keyword' => $data['keyword'],
                'lang' => $data['lang'] ?? 'und',
            ]);
        }

        return response()->json(['ok' => true, 'item' => $item]);
    }

    public function export(Request $request): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $items = UserKeyword::where('user_id', $check['user']->id)
            ->orderByDesc('id')
            ->get(['emoji_slug', 'keyword', 'lang']);

        return response()->json(['ok' => true, 'items' => $items]);
    }

    public function import(Request $request): JsonResponse
    {
        $check = $this->ensureUser($request);
        if (!isset($check['user'])) {
            return response()->json(['ok' => false, 'error' => $check['error']], $check['status']);
        }

        $data = $request->validate([
            'items' => 'required|array',
            'items.*.emoji_slug' => 'required|string|max:120',
            'items.*.keyword' => 'required|string|max:200',
            'items.*.lang' => 'nullable|string|max:10',
        ]);

        $count = 0;
        $skipped = 0;
        $user = $check['user'];
        $limit = $this->keywordLimitFor($user);
        $current = UserKeyword::where('user_id', $user->id)->count();
        foreach ($data['items'] as $row) {
            $exists = UserKeyword::where('user_id', $user->id)
                ->where('emoji_slug', $row['emoji_slug'])
                ->where('keyword', $row['keyword'])
                ->exists();

            if (!$exists && $limit !== null && $current >= $limit) {
                $skipped += 1;
                continue;
            }
            UserKeyword::updateOrCreate(
                [
                    'user_id' => $user->id,
                    'emoji_slug' => $row['emoji_slug'],
                    'keyword' => $row['keyword'],
                ],
                [
                    'lang' => $row['lang'] ?? 'und',
                ]
            );
            if (!$exists) {
                $current += 1;
            }
            $count += 1;
        }

        return response()->json(['ok' => true, 'imported' => $count, 'skipped' => $skipped]);
    }

    private function keywordLimitFor($user): ?int
    {
        if ((string) ($user->tier ?? 'free') === 'personal') {
            return null;
        }

        return (int) config('dewemoji.pagination.free_max_limit', 20);
    }
}
