<?php
/**
 * Data manipulation for the docuemnts
 */
 class DocumentsModel{
    private $specialDocumentTypes = [2, 3, 5, 7, 10];
    //orderQuestionaire, configuration, customerAcceptance, OrderAgreement, installationProtocol

     /**
      * get linked packages to a documnet
      * @param  INT $idDocument id of the document
      * @return HashArray       Array of packages for each document
      */
     private function getLinkedPackages($idDocument = 0){
         global $database;
         $data = [];
         $whereSql = '';
         if(intval($idDocument) !== 0){
             $whereSql = " AND d.id=$idDocument";
         }

         $sql = "SELECT d.id AS idDocument,
                        p.name AS packageName
                FROM ".TABLES['documents']." d
                INNER JOIN ".TABLES['rel_package_documents']." rpd
                    ON rpd.idDocument=d.id
                INNER JOIN ".TABLES['packages']." p
                    ON p.id=rpd.idPackage
                WHERE d.uploadedBy IS NULL $whereSql";
        $query = $database->query($sql);

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

        return $data;
     }

     /**
      * get documents for view documetns
      * @param  INT $idDocument id for the doceument
      * @param  INT $idPackage  id for the pacakge
      * @return Array             array of documents
      */
     public function getDocuments($idDocument, $idPackage){
         global $database;
         $data = [];
         $whereSql = '';
         $extraJoin = '';
         $idDocument = $database->escapeValue($idDocument);
         $idPackage = $database->escapeValue($idPackage);

         if(intval($idDocument) !== 0){
             $whereSql = " AND d.id=$idDocument";
         }

         if(intval($idPackage) !== 0){
             $extraJoin = " INNER JOIN ".TABLES['rel_package_documents']." rpd
                            ON rpd.idDocument=d.id AND rpd.idPackage=$idPackage";
         }

         $linkedPackages = $this->getLinkedPackages($idDocument, $idPackage);
         $specialDocumentTypesSql = implode(',', $this->specialDocumentTypes);

         $sql = "SELECT d.id AS idDocument,
                    d.documentName,
                    d.documentPath,
                    dt.type AS documentType,
                    d.extension
                FROM ".TABLES['documents']." d
                INNER JOIN ".TABLES['document_types']." dt
                    ON dt.id=d.idDocumentType
                $extraJoin
                WHERE dt.id NOT IN($specialDocumentTypesSql) $whereSql
                ORDER BY documentType, documentName";
        $query = $database->query($sql);

        while($row = $database->fetchArray($query)){
            if(isset($linkedPackages[$row['idDocument']])){
                $row['packages'] = $linkedPackages[$row['idDocument']];
            }
            $data[$row['documentType']][] = $row;
        }

         return $data;
     }

     /**
      * get packages to link to the documents
      * @return HashArray array of packages
      */
     public function getPackages(){
         global $database;
         $data = [];
         $specialDocumentTypesSql = implode(',', $this->specialDocumentTypes);

         $sql = "SELECT p.id AS idPackage,
                        p.name AS packageName,
                        c.code AS countryCode,
                        docs.idDocument,
                        docs.documentName,
                        docs.extension,
                        docs.documentType
                FROM ".TABLES['packages']." p
                INNER JOIN ".TABLES['countries']." c
                ON c.id=p.idCountry
                LEFT OUTER JOIN
                (
                    SELECT
                        rpd.idPackage,
                        rpd.idDocument,
                        d.documentName,
                        d.extension,
                        dt.type AS documentType
                    FROM ".TABLES['rel_package_documents']." rpd
                    INNER JOIN ".TABLES['documents']." d
                        ON rpd.idDocument=d.id
                    INNER JOIN ".TABLES['document_types']." dt
                        ON dt.id=d.idDocumentType
                    WHERE dt.id NOT IN($specialDocumentTypesSql)
                ) docs
                    ON p.id=docs.idPackage
                ORDER BY documentType, documentName";
         $query = $database->query($sql);
         while($row = $database->fetchArray($query)){
             $idPackage = $row['idPackage'];
             $packageDetails[$idPackage]['idPackage'] = $idPackage;
             $packageDetails[$idPackage]['packageName'] = $row['packageName'];
             $packageDetails[$idPackage]['countryCode'] = $row['countryCode'];
             unset($row['idPackage']);
             unset($row['packageName']);
             unset($row['countryCode']);

             if(!isset($packageDetails[$idPackage]['documents'])){
                 $packageDetails[$idPackage]['documents'] = [];
             }

             if($row['idDocument']){
                 $packageDetails[$idPackage]['documents'][] = $row;
             }
         }

         foreach($packageDetails as $details) {
             $data[] = $details;
         }
         usort($data, array($this, "comparePackNames"));

         return $data;
     }

     /**
      * compare package names and sort them
      * @param  Array $a first array from all packages with details
      * @param  Array $b second array from all packages with details
      * @return Int    < 0 if a is less than b; > 0 if a is greater than b, and 0 if they are equal
      */
     private function comparePackNames($a, $b) {
        return strcmp($a['packageName'], $b['packageName']);
     }

     /**
      * get documents and packages for link documents view
      * @return HashArray array containg the documents and the packages
      */
     public function getDocumentsAndPackages(){
         global $database;
         $data = [];
         $specialDocumentTypesSql = implode(',', $this->specialDocumentTypes);

         $sql = "SELECT d.id AS idDocument,
                        d.documentName,
                        d.extension,
                        dt.type AS documentType
                FROM ".TABLES['documents']." d
                INNER JOIN ".TABLES['document_types']." dt
                    ON d.idDocumentType=dt.id
                WHERE dt.id NOT IN ($specialDocumentTypesSql)
                ORDER BY documentType, d.documentName";

         $data['documents'] = $database->fetchResultArray($sql);
         $data['packages'] = $this->getPackages();

         return $data;
     }

     public function updatePackageDocuments($idPackage, $documents){
         global $database;
         $data = [];
         $idPackage = $database->escapeValue($idPackage);
         $documents = json_decode($documents);

         if(intval($idPackage) == 0){
             $data['messages'][] = [
                     'code' => 'error',
                     'message' => 'INVALID_PACKAGE'
             ];
         }

         $sql = "";
         $idsToNotDelete = "AND idDocument NOT IN(";
         foreach ($documents as $document) {
             $document->idDocument = $database->escapeValue($document->idDocument);
             $sql .= "($idPackage, ".$document->idDocument."),";
             $idsToNotDelete .= $document->idDocument.",";
         }
         $sql = rtrim($sql, ',');
         $idsToNotDelete = rtrim($idsToNotDelete, ','). ')';

         if(!empty($sql)){
             $sql = "INSERT IGNORE INTO ".TABLES['rel_package_documents']."
                    (idPackage, idDocument)
                    VALUES $sql";
             $query = $database->query($sql);
             $inserted = $database->affectedRows();
         }else{
             $inserted = 0;
             $idsToNotDelete = "";
         }

         $sqlDel ="DELETE FROM ".TABLES['rel_package_documents']."
                    WHERE idPackage=$idPackage $idsToNotDelete";
         $query = $database->query($sqlDel);
         $deleted = $database->affectedRows();

         if($inserted > 0 || $deleted >0){
             $data['messages'][] = [
                 'code' => 'success',
                 'message' => 'DOCUMENTS_LINKED_TO_PACKAGE'
             ];
         }else{
             $data['messages'][] = [
                 'code' => 'warning',
                 'message' => 'NO_CHANGES'
             ];
         }

         return $data;
     }

     public function getDocumentTypes(){
         global $database;

         $data = [];

         $sql = "SELECT dt.id AS idDocumentType,
                        dt.type,
                        dt.isSpecialType
                FROM ".TABLES['document_types']." dt
                ORDER BY dt.type ASC";
         $query = $database->query($sql);
         while($row = $database->fetchArray($query)){
             $data[] = $row;
         }

         return $data;
     }

     public function uploadNewDocument($idDocumentType, $documentName, $file){
         global $database;
         $idDocumentType = $database->escapeValue($idDocumentType);
         $documentName = $database->escapeValue($documentName);

         if(!$documentName){
             $data['messages'][] = [
                 'code' => 'error',
                 'message' => 'NO_NAME'
             ];

             return $data;
         }

         if(!$idDocumentType){
             $data['messages'][] = [
                 'code' => 'error',
                 'message' => 'NO_TYPE'
             ];

             return $data;
         }

         $specialDocTypes = implode(',', $this->specialDocumentTypes);
         $sql = "SELECT d.id
                FROM ".TABLES['documents']." d
                WHERE d.documentName='$documentName' AND d.id NOT IN($specialDocTypes)";
         $query = $database->query($sql);
         if($database->numRows($query) > 0){
             $data['messages'][] = [
                 'code' => 'error',
                 'message' => 'NAME_EXISTS'
             ];

             return $data;
         }

         $fileManager = new FileManager();
         $data = $fileManager->uploadFile($file, $idDocumentType, $documentName);

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

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

         return $data;
     }

     public function addNewDocumnetType($documentNewType){
         $fileManager = new FileManager();
         return $fileManager->addNewDocumnetType($documentNewType);
     }

     public function removeDocument($idDocument){
         global $database;
         $fileManager = new FileManager();
         $data = $fileManager->removeDocument($idDocument);

        foreach ($data['messages'] as $messageObj) {
            if ($messageObj['code'] === 'success') {
                $sqlUnlink = "
                                DELETE
                                    FROM ".TABLES['rel_package_documents']."
                                WHERE idDocument=$idDocument";
                $query = $database->query($sqlUnlink);
            }
        }

        return $data;
     }
 }
