<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Concerns\ResolvesTenantHotel;
use App\Models\Category;
use App\Services\CategoryPresetService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;

class CategoryController extends Controller
{
    use ResolvesTenantHotel;

    // WEB ROUTES - Return views
    
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $categories = Category::all();
        $presetNames = config('category_presets.names', []);
        return view('categories.index', compact('categories', 'presetNames'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return view('categories.create');
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        $category = Category::findOrFail($id);
        return view('categories.edit', compact('category'));
    }

    /**
     * Display the specified resource.
     */
    public function show(Category $category)
    {
        return view('categories.show', compact('category'));
    }

    // CRUD OPERATIONS
    
    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): JsonResponse
    {
        try {
            $validated = $request->validate([
                'name' => 'required|string|max:255|unique:categories',
                'description' => 'nullable|string',
                'type' => 'required|in:product,service,inventory,other'
            ]);

            // Set default values for active fields

            $validated['active'] = true;
            $validated['is_active'] = true;
            $validated['hotel_id'] = Auth::user()->hotel_id;

            $category = Category::create($validated);

            return response()->json([
                'success' => true,
                'message' => 'Category created successfully',
                'category' => $category->loadCount(['vendors', 'inventoryItems'])
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create category',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id): JsonResponse
    {
        try {
            $category = Category::findOrFail($id);
            
            $validated = $request->validate([
                'name' => 'required|string|max:255|unique:categories,name,' . $id,
                'description' => 'nullable|string',
                'type' => 'required|in:product,service,inventory,other'
            ]);

            $category->update($validated);

            return response()->json([
                'success' => true,
                'message' => 'Category updated successfully',
                'category' => $category->loadCount(['vendors', 'inventoryItems'])
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update category',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id): JsonResponse
    {
        try {
            $category = Category::findOrFail($id);
            
            // Check if category is used by vendors or inventory items
            if ($category->vendors()->count() > 0 || $category->inventoryItems()->count() > 0) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot delete category. It is being used by vendors or inventory items.'
                ], 400);
            }
            
            $category->delete();

            return response()->json([
                'success' => true,
                'message' => 'Category deleted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete category',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    // API METHODS - Return JSON
    
    /**
     * Get all categories (for category management page)
     */
    public function apiIndex(): JsonResponse
    {
        return $this->getCategoriesApi();
    }

    public function apiStatus(): JsonResponse
    {
        try {
            $inventoryCount = Category::where('type', 'inventory')->count();
            $vendorCount = Category::where('type', 'product')->count();

            return response()->json([
                'success' => true,
                'data' => [
                    'inventory_count' => $inventoryCount,
                    'vendor_count' => $vendorCount,
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load category status',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function getCategoriesApi(): JsonResponse
    {
        try {
            // Temporarily remove withCount to test
            $categories = Category::all();
            // $categories = Category::withCount(['vendors', 'inventoryItems'])->get();
            
            return response()->json([
                'success' => true,
                'categories' => $categories,
                'count' => $categories->count()
            ]);
        } catch (\Exception $e) {
            // Add detailed error logging
            \Log::error('Categories API Error: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'Failed to load categories',
                'error' => $e->getMessage(),
                'trace' => env('APP_DEBUG') ? $e->getTraceAsString() : null
            ], 500);
        }
    }
    /**
     * Get only active categories (for dropdowns in vendors and inventory)
     */
    public function getActiveCategories(): JsonResponse
    {
        try {
            $categories = Category::active()
                ->select('id', 'name', 'type')
                ->orderBy('name')
                ->get();
            
            return response()->json([
                'success' => true,
                'categories' => $categories
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load active categories',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get inventory-related categories for inventory item dropdowns
     */
    public function apiInventory(): JsonResponse
    {
        try {
            $hotelId = $this->tenantHotelIdOrAbort();
            if (!$hotelId) {
                return response()->json([
                    'success' => true,
                    'categories' => [],
                    'preset_names' => [],
                ]);
            }

            $data = app(CategoryPresetService::class)->categoriesForDropdowns((int) $hotelId);

            return response()->json([
                'success' => true,
                'categories' => $data['categories'],
                'preset_names' => $data['preset_names'],
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to load inventory categories',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get single category
     */
    public function showApi($id): JsonResponse
    {
        try {
            $category = Category::withCount(['vendors', 'inventoryItems'])->findOrFail($id);
            
            return response()->json([
                'success' => true,
                'category' => $category
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Category not found',
                'error' => $e->getMessage()
            ], 404);
        }
    }

    /**
     * Get category types for dropdown
     */
    public function getTypes(): JsonResponse
    {
        $types = [
            ['value' => 'product', 'label' => 'Product'],
            ['value' => 'service', 'label' => 'Service'],
            ['value' => 'inventory', 'label' => 'Inventory'],
            ['value' => 'other', 'label' => 'Other']
        ];
        
        return response()->json([
            'success' => true,
            'types' => $types
        ]);
    }

    /**
     * API: Get category types (alias)
     */
    public function getCategoryTypes(): JsonResponse
    {
        return $this->getTypes();
    }

    /**
     * API: Get single category (alias)
     */
    public function getCategoryApi($id): JsonResponse
    {
        return $this->showApi($id);
    }

    // STATUS MANAGEMENT
    
    /**
     * Toggle category status
     */
    public function toggleStatus($id): JsonResponse
    {
        try {
            $category = Category::findOrFail($id);
            $newStatus = !$category->active;
            
            $category->update([
                'active' => $newStatus,
                'is_active' => $newStatus
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Category status updated successfully',
                'category' => $category
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update category status',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Sync status
     */
    public function syncStatus(): JsonResponse
    {
        try {
            $hotelId = $this->tenantHotelIdOrAbort();
            $vendorCount = Category::where('hotel_id', $hotelId)->whereHas('vendors')->count();
            $inventoryCount = Category::where('hotel_id', $hotelId)->whereHas('inventoryItems')->count();
            $totalCategories = Category::where('hotel_id', $hotelId)->count();

            return response()->json([
                'success' => true,
                'data' => [
                    'inventory_count' => $inventoryCount,
                    'vendor_count' => $vendorCount,
                    'total_categories' => $totalCategories,
                    'active_categories' => Category::where('hotel_id', $hotelId)->active()->count()
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to get sync status',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Force sync
     */
    public function forceSync(Request $request): JsonResponse
    {
        try {
            // This would sync categories between different systems
            // For now, just return success
            return response()->json([
                'success' => true,
                'message' => 'Categories synchronized successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to sync categories',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    // IMPORT/EXPORT METHODS
    
    /**
     * Import/Export page
     */
    public function importExport()
    {
        return view('categories.import-export');
    }

    /**
     * Export categories
     */
    public function export()
    {
        $hotelId = $this->tenantHotelIdOrAbort();
        $categories = Category::where('hotel_id', $hotelId)->get();
        $csv = "ID,Name,Description,Type,Active\n";
        
        foreach ($categories as $category) {
            $csv .= "{$category->id},{$category->name},\"{$category->description}\",{$category->type},{$category->active}\n";
        }
        
        return response($csv, 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="categories_' . date('Y-m-d') . '.csv"',
        ]);
    }

    /**
     * Import categories
     */
    public function import(Request $request)
    {
        try {
            $request->validate([
                'csv_file' => 'required|file|mimes:csv,txt'
            ]);
            
            $file = $request->file('csv_file');
            $path = $file->getRealPath();
            $data = array_map('str_getcsv', file($path));
            
            // Skip header
            array_shift($data);
            
            foreach ($data as $row) {
                if (count($row) >= 4) {
                    Category::create([
                        'name' => $row[1],
                        'description' => $row[2],
                        'type' => $row[3],
                        'active' => isset($row[4]) ? (bool)$row[4] : true,
                        'is_active' => isset($row[4]) ? (bool)$row[4] : true,
                    ]);
                }
            }
            
            return redirect()->route('categories.index')
                ->with('success', 'Categories imported successfully.');
        } catch (\Exception $e) {
            return redirect()->route('categories.import-export')
                ->with('error', 'Failed to import categories: ' . $e->getMessage());
        }
    }

    /**
     * Download import template
     */
    public function downloadTemplate()
    {
        $csv = "Name,Description,Type,Active\n";
        $csv .= "Food & Beverage,All food and beverage items,product,1\n";
        $csv .= "Cleaning Supplies,Cleaning and sanitation products,inventory,1\n";
        $csv .= "Maintenance Services,Hotel maintenance and repair services,service,1\n";
        
        return response($csv, 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="category_template.csv"',
        ]);
    }

    // UTILITY METHODS
    
    /**
     * Validate request for web form submission (non-API)
     */
    public function validateWebRequest(Request $request)
    {
        return $request->validate([
            'name' => 'required|string|max:255',
            'type' => 'required|string|max:50',
            'description' => 'nullable|string',
        ]);
    }
}