<?php

class orderExtraActions {
    const DOCUMENT_TYPES = [
        'ID_QUESTIONAIRE_DOC_TYPE' => 2, // 2 => 'orderQuestionaire'
        'ID_CONFIGURATION_DOC_TYPE' => 3, // 3 => 'configuration'
        'ID_ACCEPTANCE_DOC_TYPE' => 5, // 5 => 'customerAcceptance'
        'ID_INSTALLATION_PROTOTCOL_DOC_TYPE' => 10 // 10 => 'installationProtocol'
    ];
    const ID_INSTALLATION_CATEGORY = 2;

    /**
     * add null values for products estimations in an order
     * @param INT $idOrder   id of the order
     * @param INT $idPackage id of the order
     */
    public function addStartEstimatisonForProducts($idOrder, $idPackage){
        global $database;
        $installation = 2;

        $sql = "INSERT INTO ".TABLES['rel_order_products_estimation']."
                (idOrder, idPackage, idProduct)
                SELECT rop.idOrder, rop.idPackage, rpp.idProduct
                FROM ".TABLES['rel_package_products']." rpp
                INNER JOIN ".TABLES['rel_order_packages']." rop
                    ON rop.idPackage=rpp.idPackage AND rop.packageInstance=rpp.packageInstance
                INNER JOIN ".TABLES['suppliers_countries_products']." scp
                    ON scp.idProduct=rpp.idProduct
                WHERE rop.idOrder=$idOrder AND rop.idPackage=$idPackage AND scp.idProductCategory!=$installation";
        $query = $database->query($sql);

        return $database->affectedRows();
    }

    /**
     * get suppliers products
     * @param  INT $idOrder          id for the order
     * @param  INT $idPackage        id for the order
     * @param  String $documentType  the type of the document
     * @return Array                 Array of products estimations
     */
    public function getSuppliersByPackageOrder($idOrder, $idPackage, $documentType){
        global $database, $user;

        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $documentType = $database->escapeValue($documentType);
        $data = [];
        $whereSql = "";

        $documents = $this->getSupplierDocuments($idOrder, $idPackage, $documentType);

        if($user->getUserType() === USER_TYPES['SUPPLIER']){
            $whereSql = " AND s.idUser=".$user->getUserId();
        }

        $sql = "SELECT s.id AS idSupplier,
                       s.name AS supplierName
                FROM ".TABLES['rel_order_products_estimation']." rope
                INNER JOIN ".TABLES['suppliers_countries_products']." scp
                    ON scp.idProduct=rope.idProduct
                INNER JOIN ".TABLES['suppliers']." s
                    ON s.id=scp.idSupplier
                WHERE idOrder=$idOrder AND idPackage=$idPackage AND scp.idProductCategory!=".self::ID_INSTALLATION_CATEGORY." $whereSql
                ORDER BY s.id";
        $query = $database->query($sql);
        while($row = $database->fetchArray($query)){
            $data[$row['supplierName']]['idSupplier'] = $row['idSupplier'];
            $data[$row['supplierName']]['documents'] = isset($documents[$row['supplierName']]) ? $documents[$row['supplierName']] : [];
        }

        return $data;
    }

    /**
     * get estimations for products
     * @param  INT $idOrder   id for the order
     * @param  INT $idPackage id for the order
     * @return Array          Array of products estimations
     */
    public function getProductsEstimations($idOrder, $idPackage){
        global $database, $user;
        $idInstallationCategory = 2;

        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $data = [];
        $whereSql = "";


        $documents = $this->getSupplierDocuments($idOrder, $idPackage);
        $trackingInfo = $this->getTrackingInfo($idOrder, $idPackage);

        if($user->getUserType() === USER_TYPES['SUPPLIER']){
            $whereSql = " AND s.idUser=".$user->getUserId();
        }

        $sql = "SELECT rope.idProduct,
                       rope.estimatedDate,
                       rope.confirmedDate,
                       s.id AS idSupplier,
                       s.name AS supplierName,
                       scp.productName
                FROM ".TABLES['rel_order_products_estimation']." rope
                INNER JOIN ".TABLES['suppliers_countries_products']." scp
                    ON scp.idProduct=rope.idProduct
                INNER JOIN ".TABLES['suppliers']." s
                    ON s.id=scp.idSupplier
                WHERE idOrder=$idOrder AND idPackage=$idPackage AND scp.idProductCategory!=$idInstallationCategory $whereSql
                ORDER BY s.id,
                    scp.productName";

        $query = $database->query($sql);
        if($database->numRows($query) === 0){
            if($user->getUserType() === USER_TYPES['SUPPLIER']) {
                return $data;
            }
            $addedStartValues = $this->addStartEstimatisonForProducts($idOrder, $idPackage);
            if($addedStartValues > 0){
                return $this->getProductsEstimations($idOrder, $idPackage);
            }else{
                return $data;
            }
        }
        while($row = $database->fetchArray($query)){
            $data[$row['supplierName']]['idSupplier'] = $row['idSupplier'];
            $data[$row['supplierName']]['documents'] = isset($documents[$row['supplierName']]) ? $documents[$row['supplierName']] : [];
            $data[$row['supplierName']]['estimations'][] = $row;
            $data[$row['supplierName']]['trackings'] = isset($trackingInfo[$row['idSupplier']]) ? $trackingInfo[$row['idSupplier']] : [];
        }

        return $data;
    }

    private function isProductOwner($idProduct){
        global $user, $database;

        if($user->getUserType() === USER_TYPES['BROKER']){
            return true;
        }else if($user->getUserType() === USER_TYPES['SUPPLIER']){
            $sql = "SELECT s.id
                    FROM ".TABLES['suppliers']." s
                    INNER JOIN ".TABLES['suppliers_countries_products']." scp
                    ON scp.idSupplier=s.id
                    WHERE s.idUser=".$user->getUserId();
            $query = $database->query($sql);

            return $database->numRows($query) > 0;
        }

        return false;
    }

    private function getTrackingInfo($idOrder, $idPackage) {
        global $database;
        $data = [];

        $sql = "
                SELECT
                  roso.id AS idTracking,
                  roso.idSupplier,
                  roso.trackingNumber,
                  roso.trackingUrl
                FROM
                  ".TABLES['rel_order_supplier_options']." roso
                WHERE roso.idOrder = $idOrder
                  AND roso.idPackage = $idPackage";
        $query = $database->query($sql);

        while($row = $database->fetchArray($query)) {
            $data[$row['idSupplier']][] = $row;
        }

        return $data;
    }

    /**
     * update dates for products in an order
     * @param  INT $idOrder       id for the order
     * @param  INT $idPackage     id for the package
     * @param  INT $idProduct     id for the product
     * @param  String $estimatedDate estimated date
     * @param  String $confirmedDate confirmed date
     * @return Array                update message
     */
    public function updateProductEstimation($idOrder, $idPackage, $idProduct, $estimatedDate, $confirmedDate){
        global $database;
        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idProduct = $database->escapeValue($idProduct);
        $estimatedDate = $database->escapeValue($estimatedDate);
        $confirmedDate = $database->escapeValue($confirmedDate);
        $data = [];

        if(!$this->isProductOwner($idProduct)){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NOT_OWNER_OF_PROD'
            ];

            return $data;
        }

        if(empty($estimatedDate) && empty($confirmedDate)){
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'EMPTY_DATES'
            ];

            return $data;
        }

        $checkEstimatedDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $estimatedDate);
        $checkConfirmedDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $confirmedDate);
        if(($checkEstimatedDate && !empty($estimatedDate)) || ($checkConfirmedDate && !empty($confirmedDate))){
            $data['messages'][] = $checkEstimatedDate ? $checkEstimatedDate : [];
            $data['messages'][] = $checkConfirmedDate ? $checkConfirmedDate : [];

            return $data;
        }

        if(empty($estimatedDate)){
            $estimatedDate = $confirmedDate;
        }

        $estimatedDate = !empty($estimatedDate) ? "'$estimatedDate'" : "null";
        $confirmedDate = !empty($confirmedDate) ? "'$confirmedDate'" : "null";

        $sql = "UPDATE ".TABLES['rel_order_products_estimation']."
                SET estimatedDate=$estimatedDate,
                confirmedDate=$confirmedDate
                WHERE idOrder=$idOrder AND idPackage=$idPackage AND idProduct=$idProduct";
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'PROD_ESTIMATION_UPDATED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'warning',
                'message' => 'NO_CHANGES'
            ];
        }

        return $data;
    }

    /**
     * add tracking number and url for order/package/supplier
     * @param  INT $idOrder       id for the order
     * @param  INT $idPackage     id for the package
     * @param  INT $idSupplier    id for the supplier
     * @param  String $trackingNumber traking id
     * @param  String $trackingUrl traking url
     * @return Array                update message
     */
    public function addTracking($idOrder, $idPackage, $idSupplier, $trackingNumber, $trackingUrl) {
        global $database;
        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idSupplier = $database->escapeValue($idSupplier);
        $trackingNumber = $database->escapeValue($trackingNumber);
        $trackingUrl = $database->escapeValue($trackingUrl);
        $data = [];

        if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === FALSE) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'INVALID_URL'
            ];

            return $data;
        }

        $sql = "INSERT INTO ".TABLES['rel_order_supplier_options']." (
                  idOrder,
                  idPackage,
                  idSupplier,
                  trackingNumber,
                  trackingUrl
                )
                VALUES
                  ($idOrder, $idPackage, $idSupplier, '$trackingNumber', '$trackingUrl')";
          $query = $database->query($sql);

          if($database->affectedRows() > 0){
              $data['messages'][] = [
                  'code' => 'success',
                  'message' => 'TRAKING_ID_ADDED'
              ];
          }else{
              $data['messages'][] = [
                  'code' => 'warning',
                  'message' => 'NO_CHANGES'
              ];
          }

          return $data;
    }

    /**
     * update dates for products in an order
     * @param  INT $idTracking          id for the tracking info
     * @param  String $trackingNumber   traking id
     * @param  String $trackingUrl      traking url
     * @return Array                update message
     */
    public function updateTracking($idTracking, $trackingNumber, $trackingUrl){
        global $database;
        $idTracking = $database->escapeValue($idTracking);
        $trackingNumber = $database->escapeValue($trackingNumber);
        $trackingUrl = $database->escapeValue($trackingUrl);
        $data = [];

        if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === FALSE) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'INVALID_URL'
            ];

            return $data;
        }

        $sql = "UPDATE ".TABLES['rel_order_supplier_options']."
                SET trackingNumber='$trackingNumber',
                    trackingUrl='$trackingUrl'
                WHERE id=$idTracking";
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'TRAKING_ID_UPDATED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'warning',
                'message' => 'NO_CHANGES'
            ];
        }

        return $data;
    }

    public function removeTracking($idTracking) {
        global $database;
        $idTracking = $database->escapeValue($idTracking);
        $data = [];

        $sql = "DELETE FROM ".TABLES['rel_order_supplier_options']." WHERE id=$idTracking";
        $result = $database->query($sql);

        if($database->affectedRows()){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'TRACKING_REMOVED'
            ];
        } else {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'TRACKING_REMOVED_ERROR'
            ];
        }

        return $data;
    }

    /**
     * upload a new file for configuration
     * @param  INT $idOrder    id for the order
     * @param  INT $idPackage  id for the package
     * @param  INT $idSupplier id for supplier
     * @param  STRING $fileType the type of the file (configuration or installation)
     * @param  FILE $file      file to be uploaded
     * @return Array           upload message
     */
    public function uploadConfigurationDocument($idOrder, $idPackage, $idSupplier, $fileType, $file){
        global $database, $user;

        $idSupplier = $database->escapeValue($idSupplier);
        $fileType = $database->escapeValue($fileType);
        $idDocumentType = self::DOCUMENT_TYPES['ID_CONFIGURATION_DOC_TYPE'];
        $nameSuffix = 'config';
        $maxCount = 1;

        if($fileType === 'installationProtocol') {
            $idDocumentType = self::DOCUMENT_TYPES['ID_INSTALLATION_PROTOTCOL_DOC_TYPE'];
            $nameSuffix = 'install_protocol';
        }

        $sql = "SELECT s.idUser
                FROM ".TABLES['suppliers']." s
                WHERE s.id=$idSupplier";
        $query = $database->query($sql);
        $supplier = $database->fetchArray($query);

        $sql = "SELECT name
                FROM ".TABLES['packages']."
                WHERE id=$idPackage";
        $query = $database->query($sql);
        $package = $database->fetchArray($query);
        $documentName = isset($package['name']) ? str_replace(' ', '_', $package['name']) : '';
        $documentName .= '_'.$idSupplier.'_'.$nameSuffix;

        $sql = "
            SELECT
              d.documentName
            FROM
              ".TABLES['documents']." d
              INNER JOIN ".TABLES['rel_order_documents']." rod
                ON d.id = rod.idDocument
            WHERE rod.idOrder = $idOrder
              AND rod.idPackage = $idPackage
              AND d.idDocumentType = $idDocumentType
            ORDER BY d.id DESC
            LIMIT 1";
        $lastDocName = $database->fetchResultArray($sql);
        if($lastDocName && $lastDocName[0]['documentName']) {
            $count = explode('_', $lastDocName[0]['documentName']);
            $maxCount = intval(end($count)) + 1;
        }
        $documentName .= '_'.$maxCount;

        $fileManager = new FileManager();
        $data = $fileManager->uploadFile($file, $idDocumentType, $documentName, $supplier['idUser']);
        if(isset($data['messages'])){
            return $data;
        }

        $idDocument = $data['idDocument'];

        $sql = "INSERT INTO ".TABLES['rel_order_documents']."
                (idOrder, idPackage, idDocument, validation)
                VALUES($idOrder, $idPackage, $idDocument, 'not-required')";
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            $data['messages'][] = [
                'code' => 'success',
                'message' => 'FILE_UPLOADED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NOT_UPLOADED'
            ];
        }

        return $data;
    }

    /**
     * get documents grouped by suppliers
     * @param  INT $idOrder         id for the order
     * @param  INT $idPackage       id for the package
     * @param  String $documentType the type of the document
     * @return Array                list of documents
     */
    private function getSupplierDocuments($idOrder, $idPackage, $documentType = ''){
        global $database;
        $data = [];
        $extraWhere = '';

        if($documentType) {
            $extraWhere = "
                AND d.idDocumentType =
                  (SELECT
                    dt.id
                  FROM
                    document_types dt
                  WHERE dt.folderName = '$documentType')";
        }

        $sql = "SELECT d.id as idDocument,
                    d.documentName,
                    d.extension,
                    s.name AS supplierName
                FROM ".TABLES['documents']." d
                INNER JOIN ".TABLES['rel_order_documents']." rod
                    ON rod.idDocument=d.id
                INNER JOIN ".TABLES['suppliers']." s
                    ON s.idUser=d.uploadedBy
                WHERE rod.idOrder=$idOrder AND rod.idPackage=$idPackage $extraWhere";
        $query = $database->query($sql);
        while($row = $database->fetchArray($query)){
            $data[$row['supplierName']][] = $row;
        }

        return $data;
    }

    /**
     * save the installation company
     * @param  [type] $idOrder        [description]
     * @param  [type] $idPackage      [description]
     * @param  [type] $idInstallation [description]
     * @return [type]                 [description]
     */
    public function saveInstallationCompany($idOrder, $idPackage, $idInstallation) {
        global $database;

        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idInstallation = $database->escapeValue($idInstallation);
        $installationScheduling = new InstallationScheduling();

        if(!$idOrder || !$idPackage || !$idInstallation) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'DATA_NOT_SET'
            ];

            return $data;
        }

        $sqlSelect = "
            SELECT idProduct
            FROM ".TABLES['order_selections']."
            WHERE idOrder = $idOrder
                AND idPackage = $idPackage
        ";
        $result = $database->query($sqlSelect);

        if($database->numRows($result) > 0) {
            $sql = "
                UPDATE
                    ".TABLES['order_selections']."
                SET
                    idProduct = $idInstallation
                WHERE idOrder = $idOrder AND idPackage = $idPackage";
        } else {
            $sql = "
                INSERT INTO ".TABLES['order_selections']."
                    (idOrder, idPackage, idProduct, selectionFor)
                VALUES
                    ($idOrder, $idPackage, $idInstallation, 'installation')
            ";
        }
        $result = $database->query($sql);

        $data['messages'][] = $installationScheduling->changeInstallationCompany($idOrder, $idPackage, $idInstallation);

        return $data;
    }

    /**
     * get scheduled dates for a step
     * @param  INT $idOrder       id for the order
     * @param  INT $idPackage     id for the package
     * @param  INT $idProcessStep id for the process step
     * @return Array                array of schedueld dates
     */
    public function getScheduledDates($idOrder, $idPackage, $idProcessStep){
        global $database;
        $data = [];
        $confirmations = $this->getUserConfirmationsForSchedules($idOrder, $idPackage, $idProcessStep);

        $sql = "SELECT rosd.id AS idSchedule,
                       rosd.scheduledDate,
                       rosd.isDateConfirmed,
                       rosd.idProcessStep,
                       rosd.idPackage
                FROM ".TABLES['rel_order_scheduled_dates']." rosd
                WHERE rosd.idOrder=$idOrder AND rosd.idPackage=$idPackage AND rosd.idProcessStep=$idProcessStep
                ORDER BY rosd.scheduledDate ASC ";
        $query = $database->query($sql);
        while($row = $database->fetchArray($query)){
            $row['confirmations'] = isset($confirmations[$row['idSchedule']]) ? $confirmations[$row['idSchedule']] : [];
            $data[] = $row;
        }

        return $data;
    }

    /**
     * get user confirimations for the scheduled dates
     * @param  INT $idOrder       id for the order
     * @param  INT $idPackage     id for the pakage
     * @param  INT $idProcessStep id for the process step
     * @return Array               list of confirmations
     */
    private function getUserConfirmationsForSchedules($idOrder, $idPackage, $idProcessStep){
        global $database;
        $data = [];

        $sql = "SELECT rosc.idSchedule,
                       rosc.status,
                       u.username,
                       ut.type AS userType
                FROM ".TABLES['rel_order_schedules_confirmations']." rosc
                INNER JOIN ".TABLES['rel_order_scheduled_dates']." rosd
                    ON rosc.idSchedule=rosd.id
                INNER JOIN ".TABLES['users']." u
                    ON u.id=rosc.idUser
                INNER JOIN ".TABLES['rel_user_type']." rut
                    ON rut.idUser=u.id
                INNER JOIN ".TABLES['user_types']." ut
                    ON ut.id=rut.idType
                WHERE rosd.idOrder=$idOrder AND rosd.idPackage=$idPackage AND rosd.idProcessStep=$idProcessStep";
        $query = $database->query($sql);
        while($row = $database->fetchArray($query)){
            $data[$row['idSchedule']][] = $row;
        }

        return $data;
    }

    /**
     * add users that need to confirm the schedule date for installation
     * @param INT $idOrder    id for the order
     * @param INT $idSchedule id for the schedule
     */
    private function addRequiredConfrimationUsers($idOrder, $idSchedule){
        global $database;

        $sql = "INSERT INTO ".TABLES['rel_order_schedules_confirmations']."
                (idSchedule, idUser, status)
                SELECT $idSchedule AS idSchedule,
                    c.idUser AS idUser,
                    'pending' AS status
                FROM ".TABLES['orders']." o
                INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
                ON rclc.id=o.idCUstomerInstance
                INNER JOIN ".TABLES['customers']." c
                ON c.id=rclc.idCustomer
                WHERE o.id=$idOrder";
        $query = $database->query($sql);

        return $database->affectedRows();
    }

    /**
     * Update the estimation date for the follow up meeting from an order
     * @param  Int $idOrder        Id of the order to be modified
     * @param  Int $idProcessStep  id of the porcess to be modified
     * @param  String $estimationDate new date to be added for a follow up meeting
     * @param  String $confirmedDate  confirmed date with the customer to be added for a follow up meeting
     * @return array                 response message for the update
     */
    public function updateScheduledDates($idOrder, $idPackage, $idProcess, $idProcessStep, $idSchedule, $newDate) {
        global $database;
        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idProcess = $database->escapeValue($idProcess);
        $idProcessStep = $database->escapeValue($idProcessStep);
        $idSchedule = $database->escapeValue($idSchedule);
        $newDate = $database->escapeValue($newDate);
        $orderDetailsParams = [
            'idOrder' => $idOrder,
            'idPackage' => $idPackage,
            'idProcess' => $idProcess
        ];
        $data = [];

        if($newDate !== '') {
            $checkDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $newDate);
            if($checkDate){
                $data['messages'][] = $checkDate;
                return $data;
            }
            $newDate = "'$newDate'";
        } else {
            $newDate = "null";
        }

        if(intval($idSchedule) === 0){
            $database->beginTransaction();
            $sql = "
                INSERT INTO ".TABLES['rel_order_scheduled_dates']." (
                    idOrder,
                    idPackage,
                    idProcessStep,
                    scheduledDate,
                    isDateConfirmed
                    )
                VALUES(
                        $idOrder,
                        $idPackage,
                        $idProcessStep,
                        $newDate,
                        0
                )";
            $query = $database->query($sql);
            $newIdSchedule = $database->getInsertId();
            $affectedRows = $database->affectedRows();
            $affectedRows += $this->addRequiredConfrimationUsers($idOrder, $newIdSchedule);
            if($affectedRows > 0){
                $database->commit();
            }else{
                $database->rollback();
                $err_mes = [
                    'code' => 'error',
                    'message' => 'SERVER_ERROR'
                ];
                $data['messages'][] = $err_mes;
                return $data;
            }
        }else{
            $sql = "UPDATE ".TABLES['rel_order_scheduled_dates']."
                    SET scheduledDate=$newDate
                    WHERE id=$idSchedule";
            $query = $database->query($sql);
            $affectedRows = $database->affectedRows();
        }

        if(!$query){
            $err_mes = [
                'code' => 'error',
                'message' => 'SERVER_ERROR'
            ];
            $data['messages'][] = $err_mes;
        }

        if($affectedRows > 0){
            $sqlProcessStep = "
                SELECT ps.shortDesc
                    FROM ".TABLES['process_step']." ps
                INNER JOIN ".TABLES['rel_process_steps']." rps
                   ON rps.idStep = ps.id
                   AND rps.id = $idProcessStep
                LIMIT 1
            ";
            $result = $database->fetchResultArray($sqlProcessStep);
            $procStep = $result ? $result[0]['shortDesc'] : '';

            /*if($estimationDate) {
                $orderDetailsParams['estimatedMeetingDate'] = $estimationDate;
            }
            if($confirmedDate) {
                $orderDetailsParams['confirmedMeetingDate'] = $confirmedDate;
            }
            $data['messages'][] = $this->sendConfirmationMail('scheduleMeeting', $orderDetailsParams);*/

            $data['messages'][] = [
                'code' => 'success',
                'message' => 'ORDER_STEP_MEETING_DATE_UPDATED'
            ];
        }

        return $data;
    }

    /**
     * update the status for an existing schedule date
     * @param  INT $idSchedule id for schedule date
     * @param  string $status     new status for the schedule date
     * @return Array             update message
     */
    public function updateScheduleDateStatus($idSchedule, $status, $idOrder, $idPackage, $actionCode){
        global $database, $user;
        $idSchedule = $database->escapeValue($idSchedule);
        $data = [];

        $sql = "UPDATE ".TABLES['rel_order_schedules_confirmations']."
                SET status='$status'
                WHERE idSchedule=$idSchedule AND idUser=".$user->getUserId();
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            if($status === 'accepted' && $actionCode === 'choose-installation'){
                $sql = "UPDATE ".TABLES['orders']."
                        SET acceptanceDueDate=DATE_ADD(
                            (SELECT scheduledDate
                            FROM ".TABLES['rel_order_scheduled_dates']."
                            WHERE id=$idSchedule),
                            INTERVAL 15 DAY)
                        WHERE id=$idOrder";
                $query = $database->query($sql);
            }
            $updatedMainStatus = $this->updateScheduleGlobalStatus($idSchedule, $status);

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

            return $data;
        }else{
            $message = [
                'code' => 'error',
                'message' => 'SCHEDULE_STATUS_NOT_UPDATED'
            ];
            $data['messages'][] = $message;

            return $data;
        }
    }

    /**
     * update the status for the parent schedule date base on all users confirmation
     * @param  INT $idSchedule id for the scheduled date
     * @param  String $status     new status addded to child
     * @return INT             number of affected rows
     */
    private function updateScheduleGlobalStatus($idSchedule, $status){
        global $database;
        $confirmation = $status === 'accepted' ? 1 : -1;

        $sql = "UPDATE ".TABLES['rel_order_scheduled_dates']."
                SET isDateConfirmed=$confirmation
                WHERE id=$idSchedule";
        $query = $database->query($sql);

        return $database->affectedRows();
    }

    /**
     * get customer questionaires for a specific order
     * @param  INT $idOrder  id for the order
     * @param  String $documentType the type of the documents needed - Order Questionaire or Installation protocol
     * @return Array            array of documents
     */
    public function getOrderDocumentsPerType($idOrder, $documentType){
        global $database, $user;

        $idOrder = $database->escapeValue($idOrder);
        $documentType = $database->escapeValue($documentType);
        $data = [];

        if($documentType === 'orderQuestionaire') {
            $idDocumentType = self::DOCUMENT_TYPES['ID_QUESTIONAIRE_DOC_TYPE'];
        } else if($documentType === 'installationProtocol') {
            $idDocumentType = self::DOCUMENT_TYPES['ID_INSTALLATION_PROTOTCOL_DOC_TYPE'];
        } else {
            return [];
        }

        $sql = "SELECT d.id AS idDocument,
                d.uploadedBy,
                d.documentName,
                d.extension,
                dt.folderName AS documentTypeName,
                rod.validation,
                rod.idOrder,
                rod.idPackage
                FROM ".TABLES['documents']." d
                INNER JOIN ".TABLES['rel_order_documents']." rod
                    ON rod.idDocument=d.id
                INNER JOIN ".TABLES['document_types']." dt
                    ON d.idDocumentType=dt.id
                WHERE d.idDocumentType=$idDocumentType
                    AND rod.idOrder=$idOrder";
        $query = $database->query($sql);

        while($row = $database->fetchArray($query)) {
            $row['isUploadedByMe'] = $user->getUserId() === $row['uploadedBy'];
            unset($row['uploadedBy']);
            $data['documents'][$row['idOrder'].'-'.$row['idPackage']][] = $row;
        }

        return $data;
    }

    /**
     * send mail to broker in case of new quesionnaire upload
     * @param  INT $idOrder    id of the order
     * @param  INT $idDocument id of the document
     * @return array           mail send message
     */
    private function sendQuesionnaireUploadMail($idOrder, $idDocument){
        global $database;

        $sqlCustomerInfo = "
                            SELECT o.orderNumber,
                                    GROUP_CONCAT(DISTINCT b.mail) AS mailList
                            FROM ".TABLES['orders']." o
                            INNER JOIN ".TABLES['brokers']." b
                                ON CASE WHEN o.assignedTo is NOT NULL THEN b.id=o.assignedTo ELSE 1=1 END
                            WHERE o.id=$idOrder AND b.mail is NOT NULL
                            GROUP BY o.id";
        $query = $database->query($sqlCustomerInfo);
        $brokerInfo = $database->fetchArray($query);

        $sqlDocInfo = "
                        SELECT d.id AS idDocument,
                            d.documentName,
                            d.extension
                        FROM ".TABLES['documents']." d
                        WHERE d.id=$idDocument
                        LIMIT 1";
        $query = $database->query($sqlDocInfo);
        $documentInfo = $database->fetchArray($query);
        $params = [
            'url' => WIAAS_URL.'/api-wiaas/utils/api/downloadFile?idDocument='.$documentInfo['idDocument'].'&fileName='.$documentInfo['documentName'].'.'.$documentInfo['extension'],
            'ordersUrl' => WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$brokerInfo['orderNumber'],
            'orderNumber' => $brokerInfo['orderNumber'],
            'idOrder' => $idOrder
        ];

        $mailList = trim($brokerInfo['mailList'], ',');
        $mailList = explode(',', $mailList);

        $response = Mail::sendMail($mailList, 'Modified questionaire uploaded', 'reUploadQuestionnaireTemplate.php', $params);

        if($response){
            return [
                'code' => 'success',
                'message' => 'RE_UPLOAD_MAIL'
            ];
        }

        return [
            'code' => 'error',
            'message' => 'ERROR_MAIL_SENT'
        ];
    }

    /**
     * upload again quesionnaire
     * @param  INT $idOrder    id for the order
     * @param  INT $idPackage  id for the package
     * @param  INT $idDocument id for the document
     * @param  file $file       file to be uploaded
     * @return Array            update message
     */
    public function reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file){
        global $database, $user;
        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idDocument = $database->escapeValue($idDocument);
        $documentName = 'customerQuestionaire_'.$idOrder.'_'.$idPackage.'_'.date('Y_m_d');

        $fileManager = new FileManager();
        $data = $fileManager->updateDocument($idDocument, $file, $documentName);

        if(isset($data['messages'])){
            return $data;
        }
        $idDocument = $data['idDocument'];

        $sql = "UPDATE ".TABLES['rel_order_documents']."
                SET validation='not-validated'
                WHERE idOrder=$idOrder AND idPackage=$idPackage AND idDocument=$idDocument";
        $query = $database->query($sql);

        if($database->affectedRows() > 0){
            $data['messages'][] = $this->sendQuesionnaireUploadMail($idOrder, $idDocument);

            $data['messages'][] = [
                'code' => 'success',
                'message' => 'FILE_UPLOADED'
            ];
        }else{
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'NOT_UPLOADED'
            ];
        }

        return $data;
    }

    /**
     * get comments by type e.g stepComment, invalidQuestionaireComment, ...
     * @param  Int $idOrder       the id of the order
     * @param  Int $idPackage     the id of the package
     * @param  Int $idProcessStep the id of the process step
     * @param  String $type          the type of the comment: stepComment, invalidQuestionaireComment
     * @return Array                 the comments wanted
     */
    public function getCommentsByType($idOrder, $idPackage, $idProcessStep, $type) {
        global $database;
        $idOrder = $database->escapeValue($idOrder);
        $idPackage = $database->escapeValue($idPackage);
        $idProcessStep = $database->escapeValue($idProcessStep);
        $type = $database->escapeValue($type);
        $data = [];

        if(!$idOrder) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ORDER_ID_MISSING'
            ];
        }

        if(!$idProcessStep) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'PROCESS_STEP_MISSING'
            ];
        }

        if(!$type) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'COMMENT_TYPE_MISSING'
            ];
        }

        if(array_key_exists('messages', $data) && count($data['messages'])) {
            return $data;
        }

        $sql = "
                SELECT  rsc.comment,
                        DATE_FORMAT(rsc.addDate, '%D %b, %y') as addDate,
                        u.username AS user,
                        rsc.idOrder,
                        rsc.idPackage
                FROM ".TABLES['rel_step_comments']." rsc
                INNER JOIN ".TABLES['users']." u
                    ON u.id = rsc.idUser
                WHERE rsc.idOrder=$idOrder
                    AND rsc.idProcessStep=$idProcessStep
                    AND rsc.type='$type'
        ";

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

        while($row = $database->fetchArray($query)) {
            $data[$row['idOrder'].'-'.$row['idPackage']][] = $row;
        }

        return $data;
    }
}
