<?php

namespace App\Repositories;

use App\Models\ProductCategory;

class ProductCategoryRepository
{
    public function __construct(ProductCategory $productCategory)
    {
        $this->model = $productCategory;
    }

    /**
     * Get all categories
     *
     * @return mixed
     */
    public function all()
    {
        return $this->model->latest('id')->get();
    }

    /**
     * Paginate all categories
     *
     * @param $perPage
     * @return mixed
     */
    public function paginate($perPage)
    {
        return $this->model->latest('id')->paginate($perPage);
    }

    /**
     * Filter categories
     *
     * @param $searchTerm
     * @param $perPage
     * @return mixed
     */
    public function filter($searchTerm, $perPage)
    {
        $query = $this->model::latest('id');

        if ($searchTerm) {
            $query->where(function ($q) use ($searchTerm) {
                $q->where('name', 'LIKE', '%' . $searchTerm . '%');
            });
        }

        return $query->paginate($perPage);
    }

    /**
     * Store a new category
     *
     * @param $data
     * @return mixed
     */
    public function store($data)
    {
        return $this->model->create($data);
    }

    /**
     * Find a category
     *
     * @param $id
     * @return mixed
     */
    public function find($id)
    {
        return $this->model->findOrFail($id);
    }

    /**
     * Find a category by slug
     *
     * @param $id
     * @return mixed
     */
    public function findBySlug($slug)
    {
        return $this->model->where('slug', $slug)->firstOrFail();
    }

    /**
     * Update a category
     *
     * @param $data
     * @param $id
     * @return mixed
     */
    public function update($data, $id)
    {
        $category = $this->model->findOrFail($id);
        $category->update($data);
        return $category;
    }

    /**
     * Delete a category
     *
     * @param $id
     * @return mixed
     */
    public function delete(array $validateData)
    {
        $deleteArticles = filter_var($validateData['deleteArticles'], FILTER_VALIDATE_BOOLEAN);
        $singleDelete = filter_var($validateData['singleDelete'], FILTER_VALIDATE_BOOLEAN);

        if ($singleDelete) {
            $categoryIds = (array) $validateData['categoryIds'];
            $categoryId = $categoryIds[0];
            $category = $this->model->findOrFail($categoryId);

            if ($deleteArticles) {
                if ($category->products && $category->products->isNotEmpty()) {
                    foreach ($category->products as $product) {
                        $product->delete();
                    }
                }
                $category->delete();

                return true;
            } else {
                $movingCategoryId = $validateData['movingCategoryId'];

                $category->load('products');

                foreach ($category->products as $product) {
                    $product->category_id = $movingCategoryId;
                    $product->save();
                }

                $category->delete();

                return true;
            }
        } else {
            $categories = $this->model->whereIn('id', $validateData['categoryIds'])->with('products')->get();

            if ($deleteArticles) {

                foreach ($categories as $category) {
                    if ($category->products && $category->products->isNotEmpty()) {
                        foreach ($category->products as $product) {
                            $product->delete();
                        }
                    }
                    $category->delete();
                }

                return true;
            } else {
                $movingCategoryId = $validateData['movingCategoryId'];

                foreach ($categories as $category) {
                    $category->load('products');

                    foreach ($category->products as $product) {
                        $product->category_id = $movingCategoryId;
                        $product->save();
                    }

                    $category->delete();
                }
                return true;
            }
        }
    }

    /**
     * Categories with Products
     *
     * @return mixed
     */
    public function categoriesWithProducts()
    {
        return $this->model->latest('id')->has('products')->get();
    }
}
