<?php

namespace App\Http\Controllers;

use App\Models\Category;
use App\Http\Requests\StoreCategoryRequest;
use App\Http\Requests\UpdateCategoryRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class CategoryController extends Controller
{
    /**
     * Display a listing of categories.
     */
    public function index(Request $request)
    {
        $user = $request->user();

        // Get system categories and user's custom categories
        $categories = Category::forUser($user->id)
            ->parents()
            ->with(['children' => function ($query) {
                $query->orderBy('sort_order');
            }])
            ->orderBy('sort_order')
            ->get();

        // Separate by type
        $incomeCategories = $categories->filter(fn($c) => $c->type === 'income' || $c->type === 'both');
        $expenseCategories = $categories->filter(fn($c) => $c->type === 'expense' || $c->type === 'both');

        return view('categories.index', compact('categories', 'incomeCategories', 'expenseCategories'));
    }

    /**
     * Show the form for creating a new category.
     */
    public function create(Request $request)
    {
        $user = $request->user();

        $parentCategories = Category::forUser($user->id)
            ->active()
            ->parents()
            ->orderBy('sort_order')
            ->get();

        $type = $request->get('type', 'expense');

        return view('categories.create', compact('parentCategories', 'type'));
    }

    /**
     * Store a newly created category.
     */
    public function store(StoreCategoryRequest $request)
    {
        $data = $request->validated();
        $data['user_id'] = $request->user()->id;
        $data['slug'] = Str::slug($data['name']);

        // Ensure unique slug for this user
        $existingSlug = Category::where('user_id', $data['user_id'])
            ->where('slug', $data['slug'])
            ->exists();

        if ($existingSlug) {
            $data['slug'] = $data['slug'] . '-' . uniqid();
        }

        // Set sort order
        $maxSortOrder = Category::where('user_id', $data['user_id'])
            ->where('parent_id', $data['parent_id'] ?? null)
            ->max('sort_order') ?? -1;
        $data['sort_order'] = $maxSortOrder + 1;

        Category::create($data);

        return redirect()->route('categories.index')
            ->with('success', 'Category created successfully.');
    }

    /**
     * Show the form for editing the category.
     */
    public function edit(Request $request, Category $category)
    {
        // Can only edit user's own categories, not system ones
        if ($category->is_system && $category->user_id === null) {
            return redirect()->route('categories.index')
                ->with('error', 'System categories cannot be edited.');
        }

        // Authorization handled by route model binding in AppServiceProvider
        $user = $request->user();

        $parentCategories = Category::forUser($user->id)
            ->active()
            ->parents()
            ->where('id', '!=', $category->id)
            ->orderBy('sort_order')
            ->get();

        return view('categories.edit', compact('category', 'parentCategories'));
    }

    /**
     * Update the specified category.
     */
    public function update(UpdateCategoryRequest $request, Category $category)
    {
        if ($category->is_system && $category->user_id === null) {
            return redirect()->route('categories.index')
                ->with('error', 'System categories cannot be edited.');
        }

        // Authorization handled by route model binding in AppServiceProvider
        $data = $request->validated();

        // Update slug if name changed
        if (isset($data['name']) && $data['name'] !== $category->name) {
            $data['slug'] = Str::slug($data['name']);

            // Ensure unique slug
            $existingSlug = Category::where('user_id', $category->user_id)
                ->where('slug', $data['slug'])
                ->where('id', '!=', $category->id)
                ->exists();

            if ($existingSlug) {
                $data['slug'] = $data['slug'] . '-' . uniqid();
            }
        }

        $category->update($data);

        return redirect()->route('categories.index')
            ->with('success', 'Category updated successfully.');
    }

    /**
     * Remove the specified category.
     */
    public function destroy(Category $category)
    {
        if ($category->is_system) {
            return redirect()->route('categories.index')
                ->with('error', 'System categories cannot be deleted.');
        }

        // Authorization handled by route model binding in AppServiceProvider
        // Check if category has transactions
        if ($category->transactions()->count() > 0) {
            return redirect()->route('categories.index')
                ->with('error', 'Cannot delete category with transactions. Please reassign transactions first.');
        }

        // Check if category has children
        if ($category->children()->count() > 0) {
            return redirect()->route('categories.index')
                ->with('error', 'Cannot delete category with subcategories. Please delete subcategories first.');
        }

        $category->delete();

        return redirect()->route('categories.index')
            ->with('success', 'Category deleted successfully.');
    }

    /**
     * Reorder categories (AJAX).
     */
    public function reorder(Request $request)
    {
        $validated = $request->validate([
            'categories' => 'required|array',
            'categories.*.id' => 'required|integer|exists:categories,id',
            'categories.*.sort_order' => 'required|integer|min:0',
            'categories.*.parent_id' => 'nullable|integer|exists:categories,id',
        ]);

        foreach ($validated['categories'] as $item) {
            Category::where('id', $item['id'])
                ->where('user_id', $request->user()->id)
                ->update([
                    'sort_order' => $item['sort_order'],
                    'parent_id' => $item['parent_id'] ?? null,
                ]);
        }

        return response()->json(['success' => true]);
    }

    /**
     * Toggle category active status.
     */
    public function toggleActive(Category $category)
    {
        // Authorization handled by route model binding in AppServiceProvider
        $category->update(['is_active' => !$category->is_active]);

        return redirect()->route('categories.index')
            ->with('success', 'Category status updated.');
    }
}
