<?php

namespace App\Http\Controllers;

use App\Models\Category;
use App\Models\SubCategory;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Services\BunnyCDNService;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class CategoryController extends Controller
{

    protected $bunnyCDNService;

    public function __construct(BunnyCDNService $bunnyCDNService)
    {
        $this->bunnyCDNService = $bunnyCDNService;
    }
    public function createCategory(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:100',
            'description' => 'nullable|string',
            'slug' => 'required|string',
            'image' => 'nullable|string',
            'featured' => 'nullable|boolean',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], Response::HTTP_BAD_REQUEST);
        }

        $uploadedImageUrl = null;
        if ($base64Image = $request->input('image')) {
            $fileName = Str::uuid() . '.jpg';
            $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image));

            $tempDirectory = storage_path('app/public/temp');
            $tempFilePath = $tempDirectory . '/' . $fileName;

            if (!file_exists($tempDirectory)) {
                mkdir($tempDirectory, 0777, true);
            }

            file_put_contents($tempFilePath, $imageData);

            $uploadedImageUrl = $this->bunnyCDNService->uploadImage($tempFilePath, $fileName);

            unlink($tempFilePath);
        }


        $category = Category::create([
            'name' => $request->name,
            'slug' => $request->slug,
            'description' => $request->description,
            'image' => $uploadedImageUrl,
            'featured' => $request->featured,

        ]);

        return response()->json([
            'message' => 'Category created successfully.',
        ], Response::HTTP_CREATED);
    }

    public function createSubcategory(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:100',
            'description' => 'nullable|string',
            'image' => 'nullable|string',
            'slug' => 'required|string',

            'category_id' => 'required|exists:categories,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], Response::HTTP_BAD_REQUEST);
        }


        $uploadedImageUrl = null;
        if ($base64Image = $request->input('image')) {
            $fileName = Str::uuid() . '.jpg';
            $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image));

            $tempDirectory = storage_path('app/public/temp');
            $tempFilePath = $tempDirectory . '/' . $fileName;

            if (!file_exists($tempDirectory)) {
                mkdir($tempDirectory, 0777, true);
            }

            file_put_contents($tempFilePath, $imageData);

            $uploadedImageUrl = $this->bunnyCDNService->uploadImage($tempFilePath, $fileName);

            unlink($tempFilePath);
        }

        $subcategory = SubCategory::create([
            'name' => $request->name,
            'description' => $request->description,
            'image' => $uploadedImageUrl,
            'slug' => $request->slug,
            'category_id' => $request->category_id,
        ]);

        return response()->json([
            'message' => 'Subcategory created successfully.',
            'data' => $subcategory,
        ], Response::HTTP_CREATED);
    }

    public function updateCategory(Request $request, $id)
    {
        $category = Category::find($id);

        if (!$category) {
            return response()->json(['message' => 'Category not found.'], Response::HTTP_NOT_FOUND);
        }

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:100',
            'description' => 'nullable|string',
            'slug' => 'required|string',
            'image' => 'nullable|string',
            'featured' => 'nullable|boolean',

        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], Response::HTTP_BAD_REQUEST);
        }

        $uploadedImageUrl = $category->image;
        $base64Image = $request->input('image');

        if (!empty($base64Image) && $base64Image !== $category->image) {
            $fileName = Str::uuid() . '.jpg';
            $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image));

            $tempDirectory = storage_path('app/public/temp');
            $tempFilePath = $tempDirectory . '/' . $fileName;

            if (!file_exists($tempDirectory)) {
                mkdir($tempDirectory, 0777, true);
            }

            file_put_contents($tempFilePath, $imageData);

            $cdnUrl = $this->bunnyCDNService->uploadImage($tempFilePath, $fileName);

            if ($cdnUrl) {
                $uploadedImageUrl = $cdnUrl;
            }

            unlink($tempFilePath);
        }
        $category->image = $uploadedImageUrl;
        $category->slug = $request->slug;
        $category->featured = $request->featured;

        $category->name = $request->name;
        $category->description = $request->description;
        $category->save();

        return response()->json(['message' => 'Category updated successfully.', 'data' => $category], Response::HTTP_OK);
    }

    public function updateSubcategory(Request $request, $id)
    {
        $subcategory = SubCategory::find($id);

        if (!$subcategory) {
            return response()->json(['message' => 'Subcategory not found.'], Response::HTTP_NOT_FOUND);
        }

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:100',
            'description' => 'nullable|string',
            'slug' => 'nullable|string',

            'image' => 'nullable|string',
            'category_id' => 'required|exists:categories,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed.',
                'errors' => $validator->errors(),
            ], Response::HTTP_BAD_REQUEST);
        }

        $uploadedImageUrl = $subcategory->image;
        $base64Image = $request->input('image');

        if (!empty($base64Image) && $base64Image !== $subcategory->image) {
            $fileName = Str::uuid() . '.jpg';
            $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image));

            $tempDirectory = storage_path('app/public/temp');
            $tempFilePath = $tempDirectory . '/' . $fileName;

            if (!file_exists($tempDirectory)) {
                mkdir($tempDirectory, 0777, true);
            }

            file_put_contents($tempFilePath, $imageData);

            $cdnUrl = $this->bunnyCDNService->uploadImage($tempFilePath, $fileName);

            if ($cdnUrl) {
                $uploadedImageUrl = $cdnUrl;
            }

            unlink($tempFilePath);
        }
        $subcategory->image = $uploadedImageUrl;
        $subcategory->slug = $request->slug;

        $subcategory->name = $request->name;
        $subcategory->description = $request->description;
        $subcategory->category_id = $request->category_id;
        $subcategory->save();

        return response()->json(['message' => 'Subcategory updated successfully.', 'data' => $subcategory], Response::HTTP_OK);
    }

    public function deleteCategory($id)
    {
        $category = Category::find($id);

        if (!$category) {
            return response()->json(['message' => 'Category not found.'], Response::HTTP_NOT_FOUND);
        }


        $category->delete();

        return response()->json(['message' => 'Category deleted successfully.'], Response::HTTP_OK);
    }

    public function deleteSubcategory($id)
    {
        $subcategory = SubCategory::find($id);

        if (!$subcategory) {
            return response()->json(['message' => 'Subcategory not found.'], Response::HTTP_NOT_FOUND);
        }


        $subcategory->delete();

        return response()->json(['message' => 'Subcategory deleted successfully.'], Response::HTTP_OK);
    }


    public function search(Request $request)
    {
        try {
            $searchValue = $request->input('searchValue');
            $regex = strtolower($searchValue);

            $page = $request->input('page');
            $perPage = $request->input('per_page', 10);

            $query = Category::whereNull('deleted_at')
                ->with('subcategories')
                ->orderBy('created_at', 'desc');

            if ($searchValue) {
                $query->where(function ($query) use ($regex) {
                    $query->whereRaw('LOWER(name) LIKE ?', ["%{$regex}%"])
                        ->orWhereHas('subcategories', function ($subQuery) use ($regex) {
                            $subQuery->whereRaw('LOWER(name) LIKE ?', ["%{$regex}%"]);
                        });
                });
            }
            if ($page) {
                // Paginate the results
                $categories = $query->paginate($perPage, ['*'], 'page', $page);

                return response()->json([
                    'message' => 'Categories retrieved successfully.',
                    'data' => $categories->items(),
                    'total' => $categories->total(),
                    'current_page' => $categories->currentPage(),
                    'last_page' => $categories->lastPage(),
                ], Response::HTTP_OK);
            } else {
                // Paginate the results
                $categories = $query->get();

                return response()->json([
                    'message' => 'Categories retrieved successfully.',
                    'data' => $categories
                ], Response::HTTP_OK);
            }
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Internal Server Error',
                'error' => $e->getMessage(),
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function generateUniqueSlug($name, $model)
    {
        // Generate initial slug
        $slug = Str::slug($name);

        // Check if the slug already exists in the specified model
        $originalSlug = $slug;
        $count = 1;

        // Ensure the slug is unique by checking the specified model
        while ($model::where('slug', $slug)->exists()) {
            // Append a count to the original slug to make it unique
            $slug = $originalSlug . '-' . $count;
            $count++;
        }

        return $slug;
    }

    public function importCategories(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'file' => 'required|mimes:xls,xlsx|max:2048',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first(),
            ], 400);
        }

        try {
            $data = Excel::toCollection(null, $request->file('file'))->first();

            $importedCount = 0;
            $skippedCount = 0;

            foreach ($data as $key => $row) {
                if ($key === 0) {
                    continue;
                }

                if (empty($row[1])) {
                    $skippedCount++;
                    continue;
                }

                $slug = $this->generateUniqueSlug($row[1], Category::class);

                $description = $row[3] ?? 'No description provided';

                Category::create([
                    'name' => $row[1],
                    'slug' => $slug,
                    'description' => $description,
                ]);

                $importedCount++;
            }

            return response()->json([
                'success' => true,
                'message' => 'Categories imported successfully!',
                'imported' => $importedCount,
                'skipped' => $skippedCount,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'There was an error processing the file: ' . $e->getMessage(),
            ], 500);
        }
    }



    public function importSubCategories(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'file' => 'required|mimes:xls,xlsx|max:2048',
            'category_id' => 'required|exists:categories,id',

        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first(),
            ], 400);
        }

        try {
            $data = Excel::toCollection(null, $request->file('file'))->first();

            $importedCount = 0;
            $skippedCount = 0;

            foreach ($data as $key => $row) {
                if ($key === 0) {
                    continue;
                }

                if (empty($row[1])) {
                    $skippedCount++;
                    continue;
                }

                $slug = $this->generateUniqueSlug($row[1], Category::class);

                $description = $row[3] ?? 'No description provided';

                SubCategory::create([
                    'name' => $row[1],
                    'slug' => $slug,
                    'description' => $description,
                    'category_id' => $request->category_id

                ]);

                $importedCount++;
            }

            return response()->json([
                'success' => true,
                'message' => 'Categories imported successfully!',
                'imported' => $importedCount,
                'skipped' => $skippedCount,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'There was an error processing the file: ' . $e->getMessage(),
            ], 500);
        }
    }



    public function searchClient(Request $request)
    {
        try {
            $featured = $request->input('featured');

            $query = Category::query()
                ->whereNull('deleted_at')
                ->with('subcategories')
                ->orderBy('created_at', 'desc');

            if (!is_null($featured)) {
                $query->where('featured', filter_var($featured, FILTER_VALIDATE_BOOLEAN));
            }

            $categories = $query->get();

            return response()->json([
                'message' => 'Categories retrieved successfully.',
                'data' => $categories,
            ], Response::HTTP_OK);
        } catch (\Exception $e) {
            // Return a JSON response for any server error
            return response()->json([
                'message' => 'An error occurred while retrieving categories.',
                'error' => $e->getMessage(),
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}
