<?php

namespace App\Controllers;

use App\Models\Attributes;
use App\Models\Brands;
use App\Models\Category;
use App\Models\FourchettePrix;
use App\Models\Notification;
use App\Models\Products;
use App\Models\Stores;
use Config\Services;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;

class ProductCOntroller extends AdminController
{
    public function __construct()
    {
        parent::__construct();
        helper(['form', 'url']);
    }

    private $pageTitle = 'Produits';

    public function index()
    {
        $Stores = new Stores();
        $this->verifyRole('viewProduct');
        $data['page_title'] = $this->pageTitle;
        $Product = new Products();
        $data['motos'] = $Product->getActiveProductData();
        $data['stores'] = $Stores->getActiveStore();
        return $this->render_template('products/index', $data);
    }

    public function assign_store()
    {
        if (!$this->request->isAJAX()) {
            $response = Services::response();
            $response->setStatusCode(404, 'Page Not Found')->send();
            exit;
        }

        $data = $this->request->getJSON(true);

        if (!isset($data['product_id']) || !isset($data['store_id'])) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Paramètres manquants.'
            ])->setStatusCode(400);
        }

        $product_id = (int)$data['product_id'];
        $store_id = (int)$data['store_id'];

        $productsModel = new Products();

        $result = $productsModel->assignToStore($product_id, $store_id);

        if ($result) {
            return $this->response->setJSON([
                'success' => true,
                'message' => 'Produit assigné avec succès.'
            ]);
        } else {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Échec de la mise à jour.'
            ]);
        }
    }

    public function fetchProductData()
    {
        $result = ['data' => []];
        $Products = new Products();
        $Stores = new Stores();
    
        function convertString($name)
        {
            return "$name";
        }
    
        // ✅ Utiliser la nouvelle méthode qui filtre automatiquement par rôle et store
        $data = $Products->getProductDataByRole();
        
        // ✅ Debug : Logs pour vérifier le filtrage
        $session = session();
        $user = $session->get('user');
        log_message('debug', '=== fetchProductData ===');
        log_message('debug', 'User: ' . ($user['username'] ?? 'N/A') . ' (Group: ' . ($user['group_name'] ?? 'N/A') . ', Store: ' . ($user['store_id'] ?? 'N/A') . ')');
        log_message('debug', 'Products found: ' . count($data));
    
        foreach ($data as $key => $value) {
            // Gestion du nom du magasin
            if ($value['store_id'] == 0) {
                $store_name = "TOUS";
            } else {
                $store_info = $Stores->getStoresData($value['store_id']);
                $store_name = $store_info && isset($store_info['name']) ? $store_info['name'] : "Inconnu";
            }
    
            // Disponibilité basée sur qty ET availability
            $isInStock = ((int)$value['qty'] > 0);
            $isAvailable = ((int)$value['availability'] === 1);
            
            $isProductAvailable = $isInStock && $isAvailable;
            
            $availability = $isProductAvailable ? 
                '<span class="label label-success">En stock</span>' : 
                '<span class="label label-danger">Rupture</span>';
    
            // Construction des boutons
            $buttons = '';
            if (in_array('updateProduct', $this->permission ?? [])) {
                $buttons .= '<a href="' . base_url('products/update/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-pencil"></i></a>';
            }
    
            if (in_array('deleteProduct', $this->permission ?? [])) {
                $buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
            }
    
            if (in_array('updateProduct', $this->permission ?? [])) {
                $buttons .= ' <a href="ventes/' . $value['id'] . '" class="btn btn-default"><i class="fa fa-image"></i></a>';
            }
    
            if (in_array('updateProduct', $this->permission ?? [])) {
                $buttons .= ' <button class="btn btn-default" onclick="generateQrPdf(' . $value["id"] . ')"><i class="fa fa-qrcode"></i></button>';
            }
    
            if (in_array('viewProduct', $this->permission ?? [])) {
                $buttons .= " <a href='/ventes/show/" . $value['id'] . "' class='btn btn-default'><i class='fa fa-eye'></i></a>";
            }
    
            if (in_array('assignStore', $this->permission ?? [])) {
                $buttons .= sprintf(
                    ' <button type="button" class="btn btn-info assignbtn" title="Assigner sur un magasin" data-magasin="%s" data-products-id="%d" data-toggle="modal" data-target="#assignStoreModal"><i class="fa fa-forward"></i></button>',
                    htmlspecialchars($store_name, ENT_QUOTES),
                    (int)$value["id"]
                );
            }
            
            $imagePath = 'assets/images/product_image/' . $value['image'];
            $imageHtml = $value['image'] ? 
                '<img src="' . base_url($imagePath) . '" width="50" height="50" class="img-thumbnail">' : 
                '<div class="no-image">Aucune image</div>';
    
            $result['data'][$key] = [
                $imageHtml,
                convertString($value['sku']),
                $value['name'],
                $value['prix_vente'],
                $store_name,
                $availability,
                $buttons
            ];
        }
    
        return $this->response->setJSON($result);
    }

    public function create()
    {
        $Products = new Products();
        $Brands = new Brands();
        $Category = new Category();
        $Stores = new Stores();
        $Notification = new NotificationController();
        $Fourchette = new \App\Models\FourchettePrix();
        $this->verifyRole('createProduct');
        $data['page_title'] = $this->pageTitle;
    
        $validation = \Config\Services::validation();
        $validation->setRules([
            'nom_de_produit'   => 'required',
            'marque'           => 'required',
            'type'             => 'required',
            'numero_de_moteur' => 'required',
            'prix'             => 'required|numeric',
            'price_vente'      => 'required|numeric',
            'puissance'        => 'required',
            'store'            => 'required',
            'availability'     => 'required',
            'price_min'        => 'required|numeric',
        ]);
    
        if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) {
    
            $prix_min   = (float)$this->request->getPost('price_min');
            $prix_vente = (float)$this->request->getPost('price_vente');
    
            // --- Vérification côté serveur ---
            if ($prix_min > $prix_vente) {
                session()->setFlashdata('errors', 'Le prix de vente ne peut pas être inférieur au prix minimal.');
                return redirect()->to('/products/create')->withInput();
            }
    
            $upload_image = '';
            $file = $this->request->getFile('product_image');
            if ($file && $file->isValid() && !$file->hasMoved()) {
                $uploadResult = $this->uploadImage();
                if ($uploadResult && !strpos($uploadResult, 'Error') && !strpos($uploadResult, 'No file')) {
                    $upload_image = $uploadResult;
                }
            }
    
            $availabilityValue = (int)$this->request->getPost('availability');
            $availability = ($availabilityValue === 1) ? 1 : 0;
    
            $data = [
                'name'           => $this->request->getPost('nom_de_produit'),
                'sku'            => $this->request->getPost('numero_de_serie'),
                'price'          => $this->request->getPost('prix'),
                'qty'            => 1,
                'image'          => $upload_image,
                'description'    => $this->request->getPost('description'),
                'numero_de_moteur' => $this->request->getPost('numero_de_moteur'),
                'marque'         => $this->request->getPost('marque'),
                'chasis'         => $this->request->getPost('chasis'),
                'store_id'       => (int)$this->request->getPost('store'),
                'availability'   => $availability,
                'prix_vente'     => $prix_vente,
                'date_arivage'   => $this->request->getPost('datea'),
                'puissance'      => $this->request->getPost('puissance'),
                'cler'           => $this->request->getPost('cler'),
                'categorie_id'   => json_encode($this->request->getPost('categorie[]')),
                'etats'          => $this->request->getPost('etats'),
                'infoManquekit'  => $this->request->getPost('infoManquekit'),
                'info'           => $this->request->getPost('info'),
                'infoManque'     => $this->request->getPost('infoManque'),
                'product_sold'   => 0,
                'type'           => $this->request->getPost('type')
            ];
    
            $store_id1 = (int)$this->request->getPost('store');
    
            $productId = $Products->insert($data);
            if ($productId) {
                $Fourchette->createFourchettePrix([
                    'product_id'   => $productId,
                    'prix_minimal' => $prix_min,
                ]);
    
                session()->setFlashdata('success', 'Créé avec succès');
                $Notification->createNotification(
                    "Un nouveau Produit a été créé",
                    "COMMERCIALE",
                    $store_id1,
                    'products/'
                );
    
                return redirect()->to('/products');
            } else {
                session()->setFlashdata('errors', 'Erreur lors de la création du produit');
                return redirect()->to('products/create')->withInput();
            }
        } else {
            $data = [
                'stores'     => $Stores->getActiveStore(),
                'validation' => $validation,
                'page_title' => $this->pageTitle,
                'marque'     => $Brands->getActiveBrands(),
                'categorie'  => $Category->getActiveCategory(),
            ];
    
            return $this->render_template('products/create', $data);
        }
    }
    

    private function uploadImage()
    {
        $uploadPath = 'assets/images/product_image';
    
        if (!is_dir($uploadPath)) {
            mkdir($uploadPath, 0777, true);
        }
    
        $file = $this->request->getFile('product_image');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
            $fileExtension = strtolower($file->getExtension());
            
            if (!in_array($fileExtension, $allowedTypes)) {
                log_message('error', 'Type de fichier non autorisé: ' . $fileExtension);
                return '';
            }
    
            $newName = uniqid() . '.' . $file->getExtension();
    
            if ($file->move($uploadPath, $newName)) {
                return $newName;
            } else {
                log_message('error', 'Erreur lors du déplacement du fichier');
                return '';
            }
        }
    
        return '';
    }

    public function update(int $id)
    {
        $Products = new Products();
        $Stores   = new Stores();
        $Category = new Category();
        $Brands   = new Brands();
        $FourchettePrix = new \App\Models\FourchettePrix(); // Modèle FourchettePrix
    
        $this->verifyRole('updateProduct');
    
        $validation = \Config\Services::validation();
        $validation->setRules([
            'nom_de_produit' => 'required',
            'marque'         => 'required',
        ]);
    
        // Récupérer produit et prix minimal
        $product_data = $Products->getProductData($id);
        $prix_minimal_data = $FourchettePrix->where('product_id', $id)->first();
        $prix_minimal = $prix_minimal_data['prix_minimal'] ?? '';
    
        if ($this->request->getMethod() === 'post' && $validation->withRequest($this->request)->run()) {
    
            $availabilityValue = (int)$this->request->getPost('availability');
            $availability = ($availabilityValue === 1) ? 1 : 0;
    
            $data = [
                'name'        => $this->request->getPost('nom_de_produit'),
                'sku'         => $this->request->getPost('numero_de_serie'),
                'price'       => $this->request->getPost('price'),
                'qty'         => 1,
                'description' => $this->request->getPost('description'),
                'numero_de_moteur' => $this->request->getPost('numero_de_moteur'),
                'marque'      => $this->request->getPost('marque'),
                'chasis'      => $this->request->getPost('chasis'),
                'store_id'    => (int)$this->request->getPost('store'),
                'availability'=> $availability,
                'prix_vente'  => $this->request->getPost('price_vente'),
                'date_arivage'=> $this->request->getPost('datea'),
                'puissance'   => $this->request->getPost('puissance'),
                'cler'        => $this->request->getPost('cler'),
                'categorie_id'=> json_encode($this->request->getPost('categorie[]')),
                'etats'       => $this->request->getPost('etats'),
                'infoManquekit'=> $this->request->getPost('infoManquekit'),
                'info'        => $this->request->getPost('info'),
                'infoManque'  => $this->request->getPost('infoManque'),
                'type'        => $this->request->getPost('type'),
            ];
    
            // ---- GESTION PRIX MINIMAL ----
            $prix_minimal_saisi = (float)$this->request->getPost('price_min');
            $prix_vente         = (float)$this->request->getPost('price_vente');
    
            // Vérification serveur : prix minimal <= prix de vente
            if ($prix_minimal_saisi > 0 && $prix_vente < $prix_minimal_saisi) {
                session()->setFlashdata('errors', 'Le prix de vente ne peut pas être inférieur au prix minimal.');
                return redirect()->to('/products/update/' . $id)->withInput();
            }
    
            // Sauvegarde ou mise à jour du prix minimal
            if ($prix_minimal_data) {
                $FourchettePrix->update($prix_minimal_data['id'], [
                    'prix_minimal' => $prix_minimal_saisi
                ]);
            } else {
                $FourchettePrix->insert([
                    'product_id'   => $id,
                    'prix_minimal' => $prix_minimal_saisi
                ]);
            }
    
            // Upload image si fournie
            if ($this->request->getFile('product_image')->isValid()) {
                $uploadImage = $this->uploadImage();
                $Products->update($id, ['image' => $uploadImage]);
            }
    
            // Mise à jour du produit
            if ($Products->updateProduct($data, $id)) {
                session()->setFlashdata('success', 'Produit mis à jour avec succès.');
                return redirect()->to('/products');
            } else {
                session()->setFlashdata('errors', 'Une erreur est survenue lors de la mise à jour.');
                return redirect()->to('/products/update/' . $id);
            }
    
        } else {
            // Affichage du formulaire
            $data = [
                'stores'       => $Stores->getActiveStore(),
                'validation'   => $validation,
                'page_title'   => $this->pageTitle,
                'product_data' => $product_data,
                'categorie'    => $Category->getActiveCategory(),
                'marque'       => $Brands->getActiveBrands(),
                'prix_minimal' => $prix_minimal 
            ];
    
            return $this->render_template('products/editbackup', $data);
        }
    }
    

    public function remove()
    {
        $this->verifyRole('deleteProduct');
        $product_id = $this->request->getPost('product_id');
        $response = [];
        $Products = new Products();

        if ($product_id) {
            if ($Products->remove($product_id)) {
                $response['success'] = true;
                $response['messages'] = "Successfully removed";
            } else {
                $response['success'] = false;
                $response['messages'] = "Error in the database while removing the product information";
            }
        } else {
            $response['success'] = false;
            $response['messages'] = "Refersh the page again!!";
        }
        return $this->response->setJSON($response);
    }

    public function createByExcel()
    {
        $this->verifyRole("createProduct");

        try {
            $file = $this->request->getFile('excel_product');
            if (!$file || !$file->isValid()) {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => "Fichier invalide ou non reçu"
                ]);
            }
    
            $ext = strtolower($file->getClientExtension());
            if (!in_array($ext, ['xls', 'xlsx'])) {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => "Seuls les fichiers Excel (.xls, .xlsx) sont acceptés"
                ]);
            }
    
            $spreadsheet = IOFactory::load($file->getTempName());
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray();
    
            if (count($rows) <= 1) {
                return $this->response->setJSON([
                    'success' => false,
                    'messages' => "Le fichier ne contient pas de données"
                ]);
            }
    
            $headers = array_shift($rows);
            $headers = array_map('strtolower', $headers);
    
            $columnMapping = [
                'n° série' => 'sku',
                'marque' => 'marque',
                'désignation' => 'name',
                'fournisseur' => 'info',
                'date d\'arrivage' => 'date_arivage',
                'n° moteur' => 'numero_de_moteur',
                'châssis' => 'chasis',
                'puissance' => 'puissance',
                'clé' => 'cler',
                'prix d\'achat' => 'price',
                'prix ar' => 'prix_vente',
                'catégories' => 'categorie_id',
                'prix minimale' => 'prix_minimal',
                'magasin' => 'store_id',
                'disponibilité' => 'availability',
                'état' => 'etats',
                'pièce manquant' => 'infoManque',
                'type' => 'type',
            ];
    
            $ProductsModel = new Products();
            $BrandsModel = new Brands();
            $StoresModel = new Stores();
            $CategoryModel = new Category();
    
            $db = \Config\Database::connect();
            $db->query("SET @IMPORT_MODE = 1");
    
            $countInserted = 0;
            $errors = [];
    
            $db->transStart();
    
            try {
                foreach ($rows as $rowIndex => $row) {
                    if (empty(array_filter($row))) continue;
    
                    $data = [
                        'is_piece' => 0,
                        'product_sold' => 0,
                        'qty' => 1
                    ];
    
                    foreach ($headers as $index => $header) {
                        $header = trim($header);
                        if (isset($columnMapping[$header]) && isset($row[$index])) {
                            $field = $columnMapping[$header];
                            $value = trim($row[$index]);
    
                            switch ($field) {
                                case 'marque':
                                    if (!empty($value)) {
                                        $brand = $BrandsModel->where('name', $value)->first();
                                        if (!$brand) {
                                            $brandId = $BrandsModel->insert(['name' => $value, 'active' => 1]);
                                        } else {
                                            $brandId = $brand['id'];
                                        }
                                        $data[$field] = $brandId;
                                    }
                                    break;
                                    
                                case 'store_id':
                                    if ($value == 'TOUS' || empty($value)) {
                                        $data[$field] = 0;
                                    } else {
                                        $store = $StoresModel->where('name', $value)->first();
                                        $data[$field] = $store ? $store['id'] : 0;
                                    }
                                    break;
                                    
                                case 'date_arivage':
                                    if (!empty($value)) {
                                        try {
                                            if (is_numeric($value)) {
                                                $data[$field] = date('Y-m-d', \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp($value));
                                            } else {
                                                $data[$field] = date('Y-m-d', strtotime($value));
                                            }
                                        } catch (\Exception $e) {
                                            $data[$field] = date('Y-m-d');
                                        }
                                    }
                                    break;
                                    
                                case 'price':
                                case 'prix_vente':
                                    if (!empty($value)) {
                                        $cleanedValue = str_replace(['Ar', ' ', ','], '', $value);
                                        $data[$field] = (float)$cleanedValue;
                                    }
                                    break;
                                    
                                case 'categorie_id':
                                    if (!empty($value)) {
                                        $category = $CategoryModel->where('name', $value)->first();
                                        $data[$field] = $category ? $category['id'] : null;
                                    }
                                    break;
                                    
                                case 'availability':
                                    $data[$field] = (strtolower($value) == 'oui' || $value == '1') ? 1 : 0;
                                    break;
                                    
                                default:
                                    $data[$field] = $value;
                            }
                        }
                    }
    
                    if (empty($data['name'])) {
                        $errors[] = "Ligne " . ($rowIndex + 2) . ": Nom du produit manquant";
                        continue;
                    }
    
                    if ($ProductsModel->insert($data)) {
                        $countInserted++;
                    } else {
                        $errors[] = "Ligne " . ($rowIndex + 2) . ": Erreur lors de l'insertion";
                    }
                }
    
                $db->transComplete();
    
            } catch (\Exception $e) {
                $db->transRollback();
                throw $e;
            } finally {
                $db->query("SET @IMPORT_MODE = 0");
            }
    
            $message = "$countInserted produits importés avec succès";
            if (!empty($errors)) {
                $message .= ". Erreurs: " . implode(', ', array_slice($errors, 0, 5));
                if (count($errors) > 5) {
                    $message .= "... et " . (count($errors) - 5) . " autres erreurs";
                }
            }
    
            return $this->response->setJSON([
                'success' => $countInserted > 0,
                'messages' => $message,
                'imported' => $countInserted,
                'errors' => count($errors)
            ]);
    
        } catch (\Exception $e) {
            try {
                $db = \Config\Database::connect();
                $db->query("SET @IMPORT_MODE = 0");
            } catch (\Exception $ex) {
                // Ignorer les erreurs de désactivation
            }
    
            return $this->response->setJSON([
                'success' => false,
                'messages' => "Erreur lors de l'import: " . $e->getMessage()
            ]);
        }
    }
    
}