<?php

namespace App\Http\Controllers;

use App\Models\Tag;
use App\Traits\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class TagController extends Controller
{
    use ApiResponse;

    public function create_tag(Request $request)
    {
        $user = $request->user();

        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'color' => ['required', 'string', 'max:7'],
        ]);

        $tag = Tag::create([
            'name' => $request->name,
            'color' => $request->color,
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        activity('settings')
            ->performedOn($tag)
            ->causedBy($user)
            ->withProperties([
                'name' => $request->name,
                'color' => $request->color,
            ])
            ->log("Tag {$request->name} created by {$user->name}");

        $formattedTag = [
            'id' => $tag->id,
            'name' => $tag->name,
            'color' => $tag->color,
            'created_by' => $tag->creator ? [
                'id' => $tag->creator->id,
                'name' => $tag->creator->name,
                'image_path' => $tag->creator->image_path
                    ? Storage::disk('public')->url($tag->creator->image_path)
                    : null,
            ] : null,
            'created_at' => $tag->created_at,
            'updated_at' => $tag->updated_at,
        ];

        return $this->success('Tag created successfully', $formattedTag);
    }

    public function update_tag(Request $request)
    {
        $user = $request->user();

        $request->validate([
            'id' => ['required', 'exists:tags,id'],
            'name' => ['required', 'string', 'max:255'],
            'color' => ['required', 'string', 'max:7'],
        ]);

        $tag = Tag::findOrFail($request->id);

        $oldAttributes = $tag->only(['name', 'color']);

        $tag->update([
            'name' => $request->name,
            'color' => $request->color,
            'updated_at' => now(),
        ]);

        $tag->load('creator:id,name,image_path');

        $newAttributes = $tag->only(['name', 'color']);

        activity('settings')
            ->performedOn($tag)
            ->causedBy($user)
            ->withProperties([
                'attributes' => $newAttributes,
                'old' => $oldAttributes,
            ])
            ->log("Tag {$tag->name} updated by {$user->name}");

        $formattedTag = [
            'id' => $tag->id,
            'name' => $tag->name,
            'color' => $tag->color,
            'created_by' => $tag->creator ? [
                'id' => $tag->creator->id,
                'name' => $tag->creator->name,
                'image_path' => $tag->creator->image_path
                    ? Storage::disk('public')->url($tag->creator->image_path)
                    : null,
            ] : null,
            'created_at' => $tag->created_at,
            'updated_at' => $tag->updated_at,
        ];

        return $this->success('Tag updated successfully', $formattedTag);
    }

    public function delete_tag(Request $request)
    {
        $user = $request->user();

        $request->validate([
            'id' => ['required', 'exists:tags,id'],
        ]);

        $tag = Tag::findOrFail($request->id);

        $taskCount = DB::table('task_tags')->where('tag_id', $tag->id)->count();
        $projectCount = DB::table('project_tags')->where('tag_id', $tag->id)->count();

        if ($taskCount > 0 || $projectCount > 0) {
            return $this->error('Cannot delete tag as it is being used in tasks or projects', 400);
        }

        $tag->update([
            'is_deleted' => true,
            'deleted_at' => now(),
        ]);

        activity('settings')
            ->performedOn($tag)
            ->causedBy($user)
            ->withProperties([
                'name' => $tag->name,
                'color' => $tag->color,
            ])
            ->log("Tag {$tag->name} deleted by {$user->name}");

        return $this->success('Tag deleted successfully');
    }

    public function fetch_all_tags(Request $request)
    {
        $paginatedTags = Tag::where('is_deleted', 0)
            ->with('creator:id,name,image_path')
            ->select('id', 'name', 'color', 'created_by', 'created_at', 'updated_at')
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        $tags = $paginatedTags->getCollection()->map(function ($tag) {
            return [
                'id' => $tag->id,
                'name' => $tag->name,
                'color' => $tag->color,
                'created_by' => $tag->creator ? [
                    'id' => $tag->creator->id,
                    'name' => $tag->creator->name,
                    'image_path' => $tag->creator->image_path
                        ? Storage::disk('public')->url($tag->creator->image_path)
                        : null,
                ] : null,
                'created_at' => $tag->created_at,
                'updated_at' => $tag->updated_at,
            ];
        });

        return $this->success('Tags retrieved successfully', [
            'data' => $tags,
            'current_page' => $paginatedTags->currentPage(),
            'next_page' => $paginatedTags->hasMorePages()
                ? $paginatedTags->currentPage() + 1
                : null,
            'last_page' => $paginatedTags->lastPage(),
            'total_items' => $paginatedTags->total(),
            'per_page' => $paginatedTags->perPage(),
        ]);
    }

    public function search_tags(Request $request)
    {
        $request->validate([
            'search' => ['nullable', 'string'],
        ]);

        $tags = Tag::query();

        if (!empty($request->search)) {
            $tags->where('name', 'like', '%' . $request->search . '%');
        }

        $tags = $tags->where('is_deleted', 0)
            ->with('creator:id,name,image_path')
            ->orderBy('created_at', 'desc')
            ->get();

        $formattedTags = $tags->map(function ($tag) {
            return [
                'id' => $tag->id,
                'name' => $tag->name,
                'color' => $tag->color,
                'created_by' => $tag->creator ? [
                    'id' => $tag->creator->id,
                    'name' => $tag->creator->name,
                    'image_path' => $tag->creator->image_path
                        ? Storage::disk('public')->url($tag->creator->image_path)
                        : null,
                ] : null,
                'created_at' => $tag->created_at,
                'updated_at' => $tag->updated_at,
            ];
        });

        return $this->success('Tags retrieved successfully', $formattedTags);
    }
}
