<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\TagStoreRequest;
use App\Http\Requests\Admin\TagUpdateRequest;
use App\Models\Language;
use App\Models\Tag;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class TagController extends Controller
{
    use LogsAdminActivity;

    public function index(): View
    {
        return view('admin.tags.index');
    }

    /**
     * DataTables server-side endpoint for tags admin index.
     */
    public function records(Request $request): JsonResponse
    {
        $query = Tag::withCount('posts');

        $recordsTotal = $query->count();

        $searchValue = $request->input('search.value');
        if (! empty($searchValue)) {
            $query->where(function ($q) use ($searchValue) {
                $q->where('name', 'like', '%' . $searchValue . '%')
                  ->orWhere('slug', 'like', '%' . $searchValue . '%');
            });
        }
        $recordsFiltered = $query->count();

        $allowedSorts = ['id', 'name', 'slug', 'posts_count', 'created_at'];
        $orderColumn = 'slug';
        $orderDir = 'asc';
        if ($request->has('order.0')) {
            $colIndex = (int) $request->input('order.0.column', 0);
            $colName = $request->input("columns.$colIndex.name");
            if (in_array($colName, $allowedSorts, true)) {
                $orderColumn = $colName;
            }
            $orderDir = $request->input('order.0.dir') === 'asc' ? 'asc' : 'desc';
        }
        $query->orderBy($orderColumn, $orderDir);

        $start = (int) $request->query('start', 0);
        $length = (int) $request->query('length', 15);
        if ($length > 0) {
            $query->skip($start)->take($length);
        }

        $rows = $query->get()->map(fn (Tag $tag) => [
            'id'          => $tag->id,
            'name'        => $tag->name,
            'slug'        => $tag->slug,
            'color'       => $tag->color ?? '#6c757d',
            'icon'        => $tag->icon,
            'posts_count' => $tag->posts_count,
            'edit_url'    => route('admin.tags.edit', $tag),
            'delete_url'  => route('admin.tags.destroy', $tag),
        ]);

        return response()->json([
            'draw'            => (int) $request->query('draw', 1),
            'recordsTotal'    => $recordsTotal,
            'recordsFiltered' => $recordsFiltered,
            'data'            => $rows,
        ]);
    }

    public function create(): View
    {
        return view('admin.tags.create', ['tag' => null]);
    }

    public function store(TagStoreRequest $request): RedirectResponse
    {
        $data = $request->validated();
        $translations = $data['translations'] ?? [];
        unset($data['translations']);

        $defaultLocale = Language::where('site_default', true)
            ->where('status', true)
            ->value('a2_iso');

        $data['name'] = $translations[$defaultLocale]['name'] ?? null;
        $data['description'] = $translations[$defaultLocale]['description'] ?? null;

        $tag = Tag::create($data);

        foreach ($translations as $locale => $fieldValues) {
            foreach ($fieldValues as $field => $value) {
                $tag->setTranslation($field, $locale, (string) ($value ?? ''));
            }
        }

        $this->logCreated(
            model: $tag,
            description: "Tag #{$tag->id} created"
        );

        return redirect()->route('admin.tags.index')
            ->with('success', __('admin/posts.tag_created'));
    }

    public function edit(Tag $tag): View
    {
        return view('admin.tags.edit', compact('tag'));
    }

    public function update(TagUpdateRequest $request, Tag $tag): RedirectResponse
    {
        $data = $request->validated();
        $translations = $data['translations'] ?? [];
        unset($data['translations']);

        $defaultLocale = Language::where('site_default', true)
            ->where('status', true)
            ->value('a2_iso');

        $data['name'] = $translations[$defaultLocale]['name'] ?? $tag->name;
        $data['description'] = $translations[$defaultLocale]['description'] ?? $tag->description;

        $tag->update($data);

        foreach ($translations as $locale => $fieldValues) {
            foreach ($fieldValues as $field => $value) {
                $tag->setTranslation($field, $locale, (string) ($value ?? ''));
            }
        }

        $this->logUpdated(
            model: $tag,
            description: "Tag #{$tag->id} updated"
        );

        return redirect()->route('admin.tags.index')
            ->with('success', __('admin/posts.tag_updated'));
    }

    public function destroy(Tag $tag): RedirectResponse
    {
        $this->logDeleted(
            model: $tag,
            description: "Tag #{$tag->id} deleted"
        );

        $tag->delete();

        return redirect()->route('admin.tags.index')
            ->with('success', __('admin/posts.tag_deleted'));
    }
}
