<?php

namespace App\Models;

use CodeIgniter\Model;

class Products extends Model
{
    protected $table = 'products';
    protected $primaryKey = 'id';
    protected $allowedFields = ['name', 'sku', 'price', 'product_sold', 'qty', 'image', 'description', 'numero_de_moteur', 'marque', 'chasis', 'store_id', 'availability', 'is_piece', 'prix_vente', 'date_arivage', 'puissance', 'cler', 'categorie_id', 'etats','type', 'infoManquekit', 'info', 'infoManque'];

    /**
     * ✅ Récupérer les produits selon le rôle et le store de l'utilisateur
     */
    public function getProductDataByRole(int $id = null)
    {
        $session = session();
        $user = $session->get('user');
        
        $isAdmin = in_array($user['group_name'], ['SuperAdmin', 'Direction', 'DAF']);
        
        $builder = $this->where('is_piece', 0)
                        ->where('product_sold', 0);
        
        if (!$isAdmin) {
            if (empty($user['store_id']) || $user['store_id'] == 0) {
                $builder->where('id', -1);
            } else {
                $builder->where('store_id', $user['store_id']);
            }
        }
        
        if ($id) {
            return $builder->where('id', $id)->first();
        }
        
        return $builder->orderBy('id', 'DESC')->findAll();
    }

    public function getProductData(int $id = null)
    {
        if ($id) {
            return $this->where('id', $id)->first();
        }

        return $this->where([
            'is_piece' => 0,
            'product_sold' => 0
        ])->orderBy('id', 'DESC')->findAll();
    }

    public function getProductData2(int $id)
    {
        $builder = $this->where('is_piece', 0)
            ->where('product_sold', 0)
            ->where('store_id', $id);

        return $builder->join('brands', 'brands.id = products.marque')
            ->orderBy('products.id', 'DESC')
            ->select('brands.name as brand_name,COUNT( products.id) as total_product, products.store_id as store_id,products.*')
            ->groupBy('store_id')
            ->findAll();
    }

    public function getProductData3(int $id)
    {
        if ($id == 0) {
            return $this->where('is_piece', 0)->orderBy('id', 'DESC')->findAll();
        }

        return $this->where('is_piece', 0)->where('product_sold', 0)->where('store_id', $id)->orderBy('id', 'DESC')->findAll();
    }

    public function getProductDataStore(int $store_id, bool $excludeAvance = true, int $currentProductId = null)
    {
        $builder = $this->where('is_piece', 0)
                        ->where('product_sold', 0)
                        ->where('availability', 1)
                        ->where('store_id', $store_id);
    
        $db = \Config\Database::connect();
        
        // Sous-requête pour exclure les produits en avance
        if ($excludeAvance) {
            $subQueryAvances = $db->table('avances')
                ->select('product_id')
                ->where('active', 1)
                ->where('is_order', 0)
                ->getCompiledSelect();
    
            $builder->where("id NOT IN ($subQueryAvances)", null, false);
        }
    
        // ✅ LISTE : Exclure TOUS les produits ayant une commande (statuts 1, 2, 3)
        $subQueryOrders = $db->table('orders_item')
            ->select('orders_item.product_id')
            ->join('orders', 'orders.id = orders_item.order_id')
            ->whereIn('orders.paid_status', [1, 2, 3]) // ✅ Disparaît de la liste dès qu'il y a une commande
            ->getCompiledSelect();
    
        $builder->where("id NOT IN ($subQueryOrders)", null, false);
    
        // Exception pour le produit actuel lors de modification de commande
        if ($currentProductId) {
            $builder->orWhere('id', $currentProductId);
        }
    
        return $builder->orderBy('id', 'DESC')->findAll();
    }

    public function getActiveProductData()
    {
        return $this->where('is_piece', 0)->orderBy('id', 'DESC')->findAll();
    }

    public function assignToStore($productid = null, $storeid = null)
    {
        if (!is_null($productid) && !is_null($storeid)) {
            $this->db->table('products')
                ->where('id', $productid)
                ->update(['store_id' => $storeid]);

            return true;
        }

        return false;
    }

    public function create(array $data)
    {
        return $this->insert($data) ? true : false;
    }

    public function updateProduct(array $data, int $id)
    {
        return $this->update($id, $data) ? true : false;
    }

    public function remove(int $id)
    {
        return $this->delete($id) ? true : false;
    }

    /**
     * ✅ NOUVELLE MÉTHODE : Compteur DASHBOARD (exclut uniquement statut 3)
     * Utilisé pour afficher le nombre total de produits dans le dashboard
     */
    public function countTotalProducts()
    {
        $db = \Config\Database::connect();
        
        // Exclure produits en avance
        $subQueryAvances = $db->table('avances')
            ->select('product_id')
            ->where('active', 1)
            ->where('is_order', 0)
            ->getCompiledSelect();
        
        // ✅ Exclure UNIQUEMENT les produits avec statut 3 (livré)
        $subQueryOrders = $db->table('orders_item')
            ->select('orders_item.product_id')
            ->join('orders', 'orders.id = orders_item.order_id')
            ->where('orders.paid_status', 3) // ✅ Décompté UNIQUEMENT quand livré
            ->getCompiledSelect();
        
        return $this->where('is_piece', 0)
                    ->where('product_sold', 0)
                    ->where("id NOT IN ($subQueryAvances)", null, false)
                    ->where("id NOT IN ($subQueryOrders)", null, false)
                    ->countAllResults();
    }

    public function countAllProductsIncludingSold()
    {
        return $this->countAll();
    }

    public function getTotalProductPriceByIds(array $productIds)
    {
        try {
            $total = 0.0;

            foreach ($productIds as $id) {
                $row = $this->select('price')
                    ->where('id', $id)
                    ->first();

                if ($row && isset($row['price'])) {
                    $total += (float) $row['price'];
                }
            }

            return $total;
        } catch (\Throwable $th) {
            return false;
        }
    }

    public function getProductNameById(int $id): ?string
    {
        $product = $this->where('id', $id)->first();

        if ($product && isset($product['name'])) {
            return $product['name'];
        }

        return null;
    }

    /**
     * ✅ NOUVELLE MÉTHODE : Compteur DASHBOARD par store (exclut uniquement statut 3)
     * Compter les produits par store selon le rôle de l'utilisateur
     */
    public function countProductsByUserStore()
    {
        $session = session();
        $user = $session->get('user');
        
        $isAdmin = in_array($user['group_name'], ['DAF', 'Direction', 'SuperAdmin']);
        
        $db = \Config\Database::connect();
        
        // Exclure avances
        $subQueryAvances = $db->table('avances')
            ->select('product_id')
            ->where('active', 1)
            ->where('is_order', 0)
            ->getCompiledSelect();
        
        // ✅ Exclure UNIQUEMENT les produits livrés (statut 3)
        $subQueryOrders = $db->table('orders_item')
            ->select('orders_item.product_id')
            ->join('orders', 'orders.id = orders_item.order_id')
            ->where('orders.paid_status', 3) // ✅ Décompté UNIQUEMENT quand livré
            ->getCompiledSelect();
        
        $builder = $this->where('is_piece', 0)
                        ->where('product_sold', 0)
                        ->where("id NOT IN ($subQueryAvances)", null, false)
                        ->where("id NOT IN ($subQueryOrders)", null, false);
        
        if (!$isAdmin && !empty($user['store_id']) && $user['store_id'] != 0) {
            $builder->where('store_id', $user['store_id']);
        } elseif (!$isAdmin) {
            return 0;
        }
        
        return $builder->countAllResults();
    }
}