<?php
/**
 * Data manipulation for the model
 */
 class CoMarketModel{
     const PACKAGE_TYPES = [
         'ID_STANDARD_TYPE' => 1,
         'ID_OPTION_TYPE' => 2,
         'ID_ADDITONAL_TYPE' => 3
     ];

     public function getShopPackages($idCommercialLead, $idPackage = 0, $search = ''){
         global $database, $user;

         $whereSql = "WHERE p.status='available' AND p.idPackageType=".self::PACKAGE_TYPES['ID_STANDARD_TYPE']." ";
         $search = $database->escapeValue($search);

         if($idPackage !== 0){
             $whereSql .= " AND p.id=$idPackage";
         }

         if($search !== ''){
             $searchValues = explode(' ', $search);
             $packageCondition = '';
             $descriptionCondition = '';
             $referenceCondition = '';
             $countryCondition = '';
             foreach ($searchValues as $valueToSearch) {
                 if($valueToSearch !== ''){
                     $packageCondition .= "p.name like '%".$valueToSearch."%'"." OR ";
                     $descriptionCondition .= " p.description like '%".$valueToSearch."%'"." OR ";
                     $referenceCondition .= "p.reference='".$valueToSearch."' OR ";
                     $countryCondition .= "c.name='".$valueToSearch."' OR ";
                 }
             }
             $countryCondition = rtrim($countryCondition, ' OR ');
             $whereSql .= " AND ( $packageCondition
                                 $descriptionCondition
                                 $referenceCondition
                                 $countryCondition)";
         }

         $sql = "SELECT
                    p.id AS idPackage,
                    p.reference,
                    p.name,
                    p.photo,
                    p.photoPublicId,
                    p.description AS shortDescription,
                    price_selection.idCommercialLead,
                    c.name AS country,
                    c.code AS countryCode
                FROM
                    ".TABLES['packages']." p
                        INNER JOIN
                    ".TABLES['countries']." c ON c.id = p.idCountry
                    INNER JOIN
                    (SELECT
                        idPackage,
                            plcl.idPaymentType,
                            plcl.idCommercialLead,
                            MAX(IFNULL(idCustomer, 0)) AS idCustomer
                    FROM
                        ".TABLES['price_list_commercial_lead']." plcl
                    LEFT OUTER JOIN ".TABLES['customers']." cust
                        ON cust.id = plcl.idCustomer
                    WHERE
                        (cust.idUser = ".$user->getUserId()." OR cust.idUser IS NULL)
                        AND plcl.idCommercialLead = $idCommercialLead
                    GROUP BY plcl.idPackage , plcl.idPaymentType
                    ) AS price_selection
                        ON price_selection.idPackage = p.id
                    INNER JOIN ".TABLES['price_list_commercial_lead']." plcl
                        ON plcl.idPackage = price_selection.idPackage
                        AND plcl.idPaymentType = price_selection.idPaymentType
                        AND plcl.idCommercialLead = price_selection.idCommercialLead
                        AND IFNULL(plcl.idCustomer, 0) = price_selection.idCustomer
                        AND plcl.visibleToCustomer = 1
                    INNER JOIN
                    (SELECT
                        proc.idCountry
                    FROM ".TABLES['processes']." proc
                        GROUP BY proc.idCountry
                    ) proc_countries
                        ON proc_countries.idCountry=p.idCountry
                    $whereSql
                GROUP BY p.id
                ORDER BY p.name ASC";

         $data = [];
         $query = $database->query($sql);
         while($row = $database->fetchArray($query)){
             if(strlen($row['shortDescription']) > 300 && $idPackage === 0){
                 $row['shortDescription'] = substr($row['shortDescription'], 0, 300) . '...';
             }
             if($row['photoPublicId']) {
                 $row['photo'] = IMAGE_URL . $row['photoPublicId'];
             }
             $data[] = $row;
         }

         return ['packages' => $data];
     }

     /**
      * get all commercial leads linked to a customer
      * @return Array list of commercial leads
      */
     public function getAllCommercialLeads(){
         global $database, $user;

         $sql = "SELECT rclc.idCommercialLead,
                        cl.name as commercialLeadName,
                        u.mail as mail
                 FROM ".TABLES['rel_commercial_lead_customers']." rclc
                 INNER JOIN ".TABLES['customers']." c
                     ON c.id=rclc.idCustomer
                 INNER JOIN ".TABLES['commercial_leads']." cl
                     ON cl.id=rclc.idCommercialLead
                 INNER JOIN ".TABLES['users']." u
                     ON u.id = cl.idUser
                 WHERE rclc.isLinkEnabled=1 AND c.idUser=" . $user->getUserId();

         return  ['commercialLeads' => $database->fetchResultArray($sql)];
     }

     private function getCommercialLeadInfo($idCommercialLead){
         global $database;

         $sql = "SELECT
                    cl.name,
                    u.mail,
                    cl.phone
                FROM ".TABLES['commercial_leads']." cl
                    INNER JOIN ".TABLES['users']." u
                        ON u.id = cl.idUser
                    WHERE cl.id=$idCommercialLead
                ";

         return $database->fetchResultArray($sql);
     }

     /**
      * get package options
      * @param  INT $idPackage        id for the pacakge
      * @param  INT $idCommercialLead id for the comemrcial lead
      * @return HashArray             list of option packages grouped by group id
      */
     private function getPackageOptions($idPackage, $idCommercialLead){
         global $database;
         $data = [];
         $packages = new Packages();

         $packageOptionPrices = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_OPTION_TYPE']);

         $sql = "SELECT
                    rgo.idOptionPackage,
                    p.name AS optionName,
                    rgo.isDefault,
                    pog.id AS idGroup,
                    pog.name AS groupName,
                    p.description AS shortDescription
                FROM ".TABLES['package_option_groups']." pog
                INNER JOIN ".TABLES['rel_group_options']." rgo
                    ON rgo.idGroup=pog.id
                INNER JOIN ".TABLES['packages']." p
                    ON p.id=rgo.idOptionPackage
                WHERE pog.idPackage=$idPackage";
         $query = $database->query($sql);
         while($row = $database->fetchArray($query)){
             $idGroup = $row['idGroup'];
             $data[$idGroup]['idGroup'] = $row['idGroup'];
             unset($row['idGroup']);
             $data[$idGroup]['groupName'] = $row['groupName'];
             unset($row['groupName']);
             $row['prices'] = isset($packageOptionPrices[$row['idOptionPackage']]) ? $packageOptionPrices[$row['idOptionPackage']] : [];
             $data[$idGroup]['options'][] = $row;
         }

         return $data;
     }

     /**
      * get package additional pacakges
      * @param  INT $idPackage        id for the pacakge
      * @param  INT $idCommercialLead id for the comemrcial lead
      * @return Array             list of additonal packages
      */
     private function getAdditionalPackages($idPackage, $idCommercialLead){
         global $database;
         $data = [];
         $packages = new Packages();

         $additionalPackagesPrices = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']);
         $sql = "SELECT
                    rap.idAdditionalPackage,
                    p.name AS packageName,
                    p.description AS shortDescription
                FROM ".TABLES['rel_additional_packages']." rap
                INNER JOIN ".TABLES['packages']." p
                    ON p.id=rap.idAdditionalPackage
                WHERE rap.idPackage=$idPackage";

         $query = $database->query($sql);
         while($row = $database->fetchArray($query)){
             $row['prices'] = isset($additionalPackagesPrices[$row['idAdditionalPackage']]) ? $additionalPackagesPrices[$row['idAdditionalPackage']] : [];
             $data[] = $row;
         }

         return $data;
     }

     /**
      * get info for a pacakge that can be sold in the co-market
      * @param  INT $idCommercialLead id for the commetcial lead
      * @param  INT $idPackage        id for the package
      * @return HashArray             pacakge details(country, prices, info, documents, options, additional package)
      */
     public function getShopPackageDetails($idCommercialLead, $idPackage){
         global $database, $user;
         $countries = new Countries();
         $packages = new Packages();
         $packageDocuments = new PackageDocuments();

         $idPackage = $database->escapeValue($idPackage);
         $data = [];
         $data['country'] = $countries->getCurrencyForPackage($idPackage);
         $data['prices'] = $packages->getPricesForPackages($idCommercialLead, $idPackage, self::PACKAGE_TYPES['ID_STANDARD_TYPE']);
         $data['prices'] = isset($data['prices'][$idPackage]) ? $data['prices'][$idPackage] : [];

         if(empty( $data['prices'])){
             return [];
         }

         $documents = $packageDocuments->getPackageDocuments($idPackage);
         $data['documents'] = isset($documents[$idPackage]) ? $documents[$idPackage] : [];
         $shopPackages = $this->getShopPackages($idCommercialLead, $idPackage);
         $data['packageInfo'] = isset($shopPackages['packages'][0]) ? $shopPackages['packages'][0] : [];
         $commerciaLeads = $this->getCommercialLeadInfo($idCommercialLead);
         $data['commercialLead'] = isset($commerciaLeads[0]) ? $commerciaLeads[0] : [];
         $data['groups'] = $this->getPackageOptions($idPackage, $idCommercialLead);
         $data['additionalPackages'] = $this->getAdditionalPackages($idPackage, $idCommercialLead);

         return $data;
     }

     /**
      * insert new option when adding item to cart
      * @param  INT $idCart     id for the cart
      * @param  Object $options options to be added
      * @return INT             number of inserted items
      */
     private function insertOptionsToCart($idCart, $options){
         global $database;

         if($options === '[]' || empty((array) $options)){
             return 0;
         }

         $sql = "INSERT INTO ".TABLES['web_shop_cart_extra_packages']."
                (idCart, idExtraPackage)
                VALUES ";
         foreach ($options as $idOption => $idOptionValue) {
             $idOptionValue = $database->escapeValue($idOptionValue);
             $sql .= "($idCart, $idOptionValue),";
         }
         $sql = rtrim($sql, ",");

         $query = $database->query($sql);

         return $database->affectedRows();
     }

     /**
      * add new items to the cart
      * @param INT $idPackage id for the package
      * @param INT $idPrice   id for the price
      * @return array action message
      */
     public function addToCart($idPackage, $idPrice, $options){
         global $database, $user;
         $data = [];

         if(!$idPackage || !$idPrice){
             $err_mes = [
                 'code' => 'error',
                 'message' => 'INVALID_SELECTION'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $idPackage = $database->escapeValue($idPackage);
         $idPrice = $database->escapeValue($idPrice);

         $idUser = $user->getUserId();
         $sql = "SELECT  plcl.idCommercialLead, availableCl.idCustomerInstance
                 FROM ".TABLES['price_list_commercial_lead']." plcl
                 INNER JOIN
                 (
                     SELECT rclc.idCommercialLead, rclc.id as idCustomerInstance
                     FROM ".TABLES['customers']." cust
                     INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
                     ON cust.id=rclc.idCustomer AND rclc.isLinkEnabled=1
                     WHERE cust.idUser=$idUser
                 ) availableCl
                 ON availableCl.idCommercialLead = plcl.idCommercialLead
                 WHERE plcl.id=$idPrice
                 LIMIT 1";
         $customer = $database->fetchResultArray($sql);

         if(count($customer) !== 1){
             $err_mes = [
                 'code' => 'error',
                 'message' => 'INVALID_USER'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $sql = "SELECT rclc.idCommercialLead
                FROM ".TABLES['rel_commercial_lead_customers']." rclc
                INNER JOIN ".TABLES['web_shop_cart']." wsc
                    ON wsc.idCustomerInstance=rclc.id
                INNER JOIN ".TABLES['customers']." c
                    ON c.id=rclc.idCustomer
                WHERE c.idUser=$idUser
                LIMIT 1
                ";
         $alreadySelectedCL = $database->fetchResultArray($sql);
         if(count($alreadySelectedCL) > 0 && $alreadySelectedCL[0]['idCommercialLead'] !== $customer[0]['idCommercialLead']){
             $err_mes = [
                 'code' => 'warning',
                 'message' => 'ONLY_ONE_CL'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $sql = "SELECT
                    COUNT(DISTINCT idCountry) AS differentCountries
                FROM
                    (SELECT DISTINCT
                        p.idCountry
                    FROM
                        ".TABLES['web_shop_cart']." wsc
                    INNER JOIN ".TABLES['packages']." p
                        ON wsc.idPackage = p.id
                    WHERE
                        idCustomerInstance =  ".$customer[0]['idCustomerInstance']." AND idUser = $idUser
                    UNION ALL
                    SELECT
                        p.idCountry
                    FROM
                        ".TABLES['packages']." p
                    WHERE
                        p.id = $idPackage) countires";
         $countriesCount = $database->fetchResultArray($sql)[0];
         if(intval($countriesCount['differentCountries']) > 1){
             $err_mes = [
                 'code' => 'warning',
                 'message' => 'ONLY_ONE_COUNTRY'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $sqlCheckPackage = "
                    SELECT idPackage
                        FROM ".TABLES['web_shop_cart']."
                    WHERE idPackage = $idPackage
                        AND idCustomerInstance = ".$customer[0]['idCustomerInstance']."
                        AND idUser = $idUser
        ";
         $result = $database->query($sqlCheckPackage);
         if($database->numRows($result) > 0){
             $err_mes = [
                 'code' => 'error',
                 'message' => 'PACKAGE_ALREADY_IN_CART'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $sqlPackageInstance = "SELECT MAX(rpp.packageInstance) as maxInstance
                                FROM ".TABLES['rel_package_products']." rpp
                                WHERE rpp.idPackage=$idPackage";
         $result = $database->fetchResultArray($sqlPackageInstance);
         if(count($result) === 0){
             $err_mes = [
                 'code' => 'error',
                 'message' => 'PACKAGE_ERROR'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }
         $maxPackageInstance = $result[0]['maxInstance'];

         $sqlIns = "INSERT INTO ".TABLES['web_shop_cart']."
                    (idPackage, idCustomerInstance, idPrice, idUser, quantity, packageInstance)
                    VALUES($idPackage,
                        ".$customer[0]['idCustomerInstance'].",
                        $idPrice,
                        $idUser,
                        1,
                        $maxPackageInstance)";

         $query = $database->query($sqlIns);
         $idCart = $database->getInsertId();

         if($database->affectedRows() !== 1){

             $err_mes = [
                 'code' => 'error',
                 'message' => 'PACKAGE_ALREADY_IN_CART'
             ];
             $data['messages'][] = $err_mes;

             return $data;
         }

         $insertedOptions = $this->insertOptionsToCart($idCart, $options);

         if($insertedOptions){
             $mes = [
                 'code' => 'success',
                 'message' => 'OPTIONS_ADDED'
             ];
             $data['messages'][] = $mes;
         }

         $mes = [
             'code' => 'success',
             'message' => 'PACKAGE_ADDED'
         ];
         $data['messages'][] = $mes;

         return $data;
     }
 }