<?php 

namespace PrestaShop\Module\PolarisPrestaConnector\Controller;

use Symfony\Component\HttpFoundation\Request;
use PrestaShop\Module\PolarisPrestaConnector\SyncConfiguration;
use Symfony\Component\HttpFoundation\JsonResponse;

class ProductsMappingsAdminController extends ConfigurationAdminController
{    
    /**
     * Mappings produits
     */
    public function indexAction(Request $request)
    {
        $args = $request->query->all();

        // Si on a déjà confirmé, on ne demande pas une seconde fois pour toute la journée
        if (isset($_SESSION['products_mappings_filters_sure']) && $_SESSION['products_mappings_filters_sure'] == date('Y-m-d'))
            $args['sure'] = 'yes';
        
        if (!isset($args["sure"]) || $args["sure"] != "yes")
        {            
            return $this->render('@Modules/' . $this->module->name . '/views/templates/admin/products_mappings_grid.html.twig', $this->addDefaultVars([
                'sure' => 'no',
            ]));
        }
        else
            $_SESSION['products_mappings_filters_sure'] = date('Y-m-d');

        $cfg = $this->module->getCfg();

        $filters = [
            'id_product' => null,
            'id_product_attribute' => null,
            'product_name' => null,
            'variant_name' => null,
            'ean' => null,
        ];

        // On récupère les filtres de la session
        $save_filters = $_SESSION['products_mappings_filters'] ?? [];
        if (!empty($save_filters))
        {
            foreach (array_keys($filters) as $key)
            {
                if (isset($save_filters[$key]))
                    $filters[$key] = empty($save_filters[$key]) ? null : $save_filters[$key];
            }
        }

        // Puis on écrase avec les filtres passés en paramètre
        $modified = false;
        foreach (array_keys($filters) as $key)
        {
            if (isset($args[$key]))
            {
                $filters[$key] = empty($args[$key]) ? null : $args[$key];
                $modified = true;
            }
        }

        if ($modified)
            $_SESSION['products_mappings_filters'] = $filters;

        $page = isset($args['page']) ? (int) $args['page'] : 1;
        $nb_per_page = 50;

        // Obtient le contexte général
        $id_lang = (int)  \Context::getContext()->language->id;

        // Interrogation de la base de données pour récupérer le mapping des produits
        $supplierId = $this->module->getOrCreateSupplierId();

        $db = \Db::getInstance();
        $query = "
            FROM "._DB_PREFIX_."product_attribute c
            LEFT JOIN "._DB_PREFIX_."product_supplier ps ON (c.id_product = ps.id_product AND c.id_product_attribute = ps.id_product_attribute AND ps.id_supplier = ".$supplierId.")
            LEFT JOIN "._DB_PREFIX_."product p ON (c.id_product = p.id_product)
            LEFT JOIN "._DB_PREFIX_."product_lang pl ON (pl.id_product = p.id_product AND pl.id_lang = ".$id_lang.")
            WHERE 1";

        $product_name_query = "CONCAT(p.reference, ' - ', pl.name)";
        $variant_name_query = "CONCAT(c.reference, ' - ', 
                COALESCE((SELECT GROUP_CONCAT(al.name SEPARATOR ' - ') FROM 
                    ps_product_attribute_combination AS pac
                    LEFT JOIN ps_attribute_lang al ON (al.id_attribute = pac.id_attribute AND al.id_lang = ".$id_lang.")                    
                    LEFT JOIN ps_attribute a ON al.id_attribute = a.id_attribute 
                    LEFT JOIN ps_attribute_group g ON a.id_attribute_group = g.id_attribute_group
                    WHERE pac.id_product_attribute = c.id_product_attribute
                    ORDER BY g.position ASC
                )), '')";

        if (!empty($filters['id_product']))
            $query .= " AND c.id_product = ".(int) $filters['id_product'];
        
        if (!empty($filters['id_product_attribute']))
            $query .= " AND c.id_product_attribute = ".(int) $filters['id_product_attribute'];

        if (!empty($filters['product_name']))
            $query .= " AND ".$product_name_query." LIKE '%" . pSQL($filters['product_name']) . "%'";

        if (!empty($filters['variant_name']))
            $query .= " AND ".$variant_name_query." LIKE '%" . pSQL($filters['variant_name']) . "%'";

        if (!empty($filters['ean']))
        {
            if ($filters['ean'] == 'vide')
                $query .= " AND (ps.product_supplier_reference IS NULL OR ps.product_supplier_reference = '')";
            else
                $query .= " AND ps.product_supplier_reference LIKE '%".pSQL($filters['ean'])."%'";
        }
        
        $count = $db->getValue("SELECT COUNT(*) as total ".$query);

        $select = "SELECT c.id_product_attribute,
            c.id_product,
            ps.product_supplier_reference, ".$product_name_query. " AS product_name,
            ".$variant_name_query." AS variant_name,
            c.reference = ps.product_supplier_reference AS linked,
            p.active";
        $order = " ORDER BY c.id_product ASC, c.id_product_attribute ASC";

        $rows = $db->executeS($select.$query.$order." LIMIT ".$nb_per_page." OFFSET ".($page - 1) * $nb_per_page);
        if ($rows === FALSE)
            throw new \Exception('Erreur à la lecture de la bdd : '. $db->getMsgError());
        $mappings_data = [];
        
        $last_product_id = 0;
        foreach ($rows as &$row)
        {
            $mappings_data[] = [                
                'id_product' => $row['id_product'] == $last_product_id ? '' : $row['id_product'],
                'product_name' => $row['id_product'] == $last_product_id ? '' : $row['product_name'],
                'id_reference' => $row['id_product_attribute'],                
                'variant_name' => $row['variant_name'],
                'ean' => $row['product_supplier_reference'],
                'linked' => $row['linked'] ? 'Oui' : 'Non',
                'locked' => $cfg->isProductLocked((int) $row['id_product']),
            ];

            $last_product_id = $row['id_product'];
        }

        return $this->render('@Modules/' . $this->module->name . '/views/templates/admin/products_mappings_grid.html.twig', $this->addDefaultVars([
            'sure' => 'yes',
            'mappings' => $mappings_data,
            'page' => $page,
            'nb_items' => $count,
            'nb_pages' => ceil($count / $nb_per_page),
            'nb_per_page' => $nb_per_page,
            'filters' => $filters,
        ]));
    }

    /**
     * Mise à jour d'un mapping produit
     */
    public function updateAjaxAction(Request $request): JsonResponse
    {
        try
        {
            $idCombination = (int) $request->request->get('id_combination');
            $supplierReference = pSQL($request->request->get('supplier_reference'));
            
            if (!$idCombination || empty($supplierReference)) {
                return new JsonResponse(['success' => false, 'message' => 'Invalid data'], 400);
            }

            // On met à jour la référence fournisseur du produit : la ligne existe ou peut-être pas !$
            $id_supplier = $this->module->getCfg()->get(SyncConfiguration::CFG_SUPPLIER);
            if (!$id_supplier)
                throw new \Exception('Fournisseur interne non configuré');
            
            $db = \Db::getInstance();

            $id_supplier_reference = $db->getValue('SELECT id_product_supplier FROM '._DB_PREFIX_.'product_supplier WHERE id_supplier = '.$id_supplier.' AND id_product_attribute = '.(int) $idCombination);
            if ($id_supplier_reference)
            {
                if (!$db->execute("UPDATE "._DB_PREFIX_."product_supplier SET product_supplier_reference = '".pSQL($supplierReference)."' WHERE id_product_supplier = ".$id_supplier_reference))
                    throw new \Exception('Erreur à la mise à jour : '. $db->getMsgError());
            }
            else
            {
                // Il faut insérer la référence plutôt que la mettre à jour
                if (!$db->execute("INSERT INTO "._DB_PREFIX_."product_supplier (id_product, id_product_attribute, id_supplier, product_supplier_reference) VALUES ((SELECT id_product FROM "._DB_PREFIX_."product_attribute WHERE id_product_attribute = ".(int) $idCombination."), ".(int) $idCombination.", ".$id_supplier.", '".pSQL($supplierReference)."')"))
                    throw new \Exception('Erreur à l\'enregistrement : '. $db->getMsgError());
            }

            return new JsonResponse(['success' => true, 'message' => 'Updated successfully']);
        }
        catch (\Exception $e)
        {
            return new JsonResponse(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}