<?php
class AddressHelper{
    /**
     * returns the delivery address information for the user logged in
     * @return Array delivery address
     */
    public function getDeliveryAddress() {
        global $database, $user;

        $sqlDelivery = "SELECT
                 da.id,
                 da.detailedAddress AS detailedAddress,
                 da.city AS city,
                 da.zip AS zipCode,
                 co.name AS countryName,
                 co.id AS idCountrySelected
               FROM
                 ".TABLES['customers']." c
                 INNER JOIN ".TABLES['delivery_addresses']." da
                   ON da.idUser = c.idUser
                 INNER JOIN ".TABLES['countries']." co
                   ON co.id = da.idCountry
               WHERE c.idUser = ".$user->getUserId()."
               ORDER BY da.id DESC
        ";

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

    /**
     * returns the billing address information for the user logged in
     * @return Array billing address info
     */
    public function getBillingAddress() {
        global $database, $user;

        $sqlBillingAddress = "SELECT
                 bi.id AS id,
                 bi.firstName AS firstName,
                 bi.lastName AS lastName,
                 bi.invoiceMail AS invoiceMail,
                 bi.idCountry AS idCountrySelected,
                 bi.detailedAddress AS detailedAddress,
                 bi.city AS city,
                 co.name AS countryName,
                 bi.zip AS zipCode
               FROM
                 ".TABLES['customers']." c
                 INNER JOIN ".TABLES['billing_information']." bi
                   ON bi.idUser = c.idUser
                 INNER JOIN ".TABLES['countries']." co
                   ON co.id = bi.idCountry
               WHERE c.idUser = ".$user->getUserId()."
               ORDER BY bi.id DESC
        ";

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

    /**
     * check the owner for the address
     * @param  INT $idProfileAddress id for delivery address
     * @return boolean               returns ture if the users is the address owner
     */
    private function checkAddressOwner($idProfileAddress){
            global $database, $user;

            $sql = "SELECT da.idUser
                    FROM ".TABLES['delivery_addresses']." da
                    WHERE da.id=$idProfileAddress AND da.idUser=".$user->getUserId();
            $query = $database->query($sql);

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

    /**
     * remove delivery address
     * @param  INT $idProfileAddress id delivery address
     * @return Array                 update message
     */
    public function removeProfileAddress($idProfileAddress){
        global $database, $user;
        $idProfileAddress = $database->escapeValue($idProfileAddress);
        $data = [];

        if(!$idProfileAddress){
            $err_mes = [
                'code' => 'error',
                'message' => 'NO_ADDRESS_SELECTED'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        if(!$this->checkAddressOwner($idProfileAddress)){
            $err_mes = [
                'code' => 'error',
                'message' => 'NOT_ADDRESS_OWNER'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        $sql = "DELETE FROM ".TABLES['delivery_addresses']."
                WHERE id=$idProfileAddress ";
        $query = $database->query($sql);
        if($database->affectedRows() > 0){
            $mes = [
                'code' => 'success',
                'message' => 'ADDRESS_REMOVED'
            ];
        }else{
            $mes = [
                'code' => 'error',
                'message' => 'ADDRESS_ERROR'
            ];
        }

        $data['messages'][] = $mes;

        return $data;
    }

    /**
     * validate data for saving address
     * @param  Object $info address information
     * @return Array       validation messages or empty if data is valid
     */
    private function validateAddressData($info, $type = 'profileAddress'){
        global $database;
        $data = [];

        foreach (get_object_vars($info) as $key => $value) {
            $info->{$key} = $database->escapeValue($value);
        }

        if(!isset($info->idCountrySelected) || empty($info->idCountrySelected)) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ADD_COUNTRY'
            ];

            return $data;
        }

        if(!isset($info->city) || empty($info->city)) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ADD_CITY'
            ];

            return $data;
        }

        $checkMessage = $database->invalidLength('city', $info->city, 100);
        if($checkMessage){
            $data['messages'][] = $checkMessage;
        }

        if(!isset($info->detailedAddress) || empty($info->detailedAddress)) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ADD_ADDRESS'
            ];

            return $data;
        }

        $checkMessage = $database->invalidLength('detailedAddress', $info->detailedAddress, 500);
        if($checkMessage){
            $data['messages'][] = $checkMessage;
        }

        if(!isset($info->zipCode) || empty($info->zipCode)) {
            $data['messages'][] = [
                'code' => 'error',
                'message' => 'ADD_ZIP'
            ];

            return $data;
        }

        $checkMessage = $database->invalidLength('zipCode', $info->zipCode, 20);
        if($checkMessage){
            $data['messages'][] = $checkMessage;
        }

        if($type === 'billingAddress'){
            if(isset($info->invoiceMail) &&  !empty($info->invoiceMail)) {
                $checkMessage = $database->invalidLength('invoiceMail', $info->invoiceMail, 300);
                if($checkMessage){
                    $data['messages'][] = $checkMessage;
                }

                if(!filter_var($info->invoiceMail, FILTER_VALIDATE_EMAIL)){
                    $data['messages'][] = [
                        'code' => 'error',
                        'message' => 'INVALID_INVOICE_MAIL'
                    ];
                }
            }
        }

        return $data;
    }

    /**
     * save delivery address
     * @param  Object $profileAddress   delivery address information
     * @return Array                    update message
     */
    public function saveProfileAddress($profileAddress){
        global $database, $user;
        $profileAddress = json_decode($profileAddress);
        $idUser = $user->getUserId();
        $data = [];
        $userHelper = new UsersHelper();

        if(!$profileAddress){
            $err_mes = [
                'code' => 'error',
                'message' => 'INVALID_PROFILE_ADDRESS'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        if(!$userHelper->checkRightsToEdit($idUser)){
            $err_mes = [
                'code' => 'error',
                'message' => 'INVALID_USER'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        $checkMessage = $this->validateAddressData($profileAddress);
        if(!empty($checkMessage)){
            return $checkMessage;
        }

        $idAddress = isset($profileAddress->id) ? $profileAddress->id : 'null';

        $sql = "INSERT INTO ".TABLES['delivery_addresses']." (id, idUser, idCountry, city, detailedAddress, zip)
                VALUES(".$idAddress.",
                    ".$idUser.",
                    ".$profileAddress->idCountrySelected.",
                    '".$profileAddress->city."',
                    '".$profileAddress->detailedAddress."',
                    '".$profileAddress->zipCode."')
                ON DUPLICATE KEY UPDATE
                    idCountry= VALUES(idCountry),
                    city= VALUES(city),
                    detailedAddress=VALUES(detailedAddress),
                    zip=VALUES(zip)";

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

        if($database->affectedRows()) {
            $mes = [
                'code' => 'success',
                'message' => 'PROFILE_ADDRESS_UPDATED'
            ];
            $data['messages'][] = $mes;
        }else{
            $mes = [
                'code' => 'warning',
                'message' => 'PROFILE_ADDRESS_NOT_CHANGED'
            ];
            $data['messages'][] = $mes;
        }

        return $data;
    }

    /**
     * check owner for billing address
     * @param  INT $idBillingAddress id for billing address
     * @return Boolean               true if use has rights to modify the billing address
     */
    private function checkBillingAddressOwner($idBillingAddress){
        global $database, $user;

        $sql = "SELECT bi.idUser
                FROM ".TABLES['billing_information']." bi
                WHERE bi.id=$idBillingAddress AND bi.idUser=".$user->getUserId();
        $query = $database->query($sql);

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

    /**
     * remove billing address
     * @param  INT $idBillingAddress   billing address information
     * @return Array                 update message
     */
    public function removeBillingAddress($idBillingAddress){
        global $database, $user;
        $idBillingAddress = $database->escapeValue($idBillingAddress);
        $data = [];

        if(!$idBillingAddress){
            $err_mes = [
                'code' => 'error',
                'message' => 'NO_ADDRESS_SELECTED'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        if(!$this->checkBillingAddressOwner($idBillingAddress)){
            $err_mes = [
                'code' => 'error',
                'message' => 'NOT_ADDRESS_OWNER'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        $sql = "DELETE FROM ".TABLES['billing_information']."
                WHERE id=$idBillingAddress ";
        $query = $database->query($sql);
        if($database->affectedRows() > 0){
            $mes = [
                'code' => 'success',
                'message' => 'BILLING_ADDRESS_REMOVED'
            ];
            $data['messages'][] = $mes;
        }else{
            $mes = [
                'code' => 'error',
                'message' => 'ADDRESS_ERROR'
            ];
            $data['messages'][] = $mes;
        }

        return $data;
    }

    /**
     * save billing address
     * @param  INT    $idCompany        id for company
     * @param  Object $billingAddress   billing address information
     * @return Array                    update message
     */
    public function saveBillingAddress($idCompany, $billingAddress){
        global $database, $user;
        $billingAddress = json_decode($billingAddress);
        $idCompany = $database->escapeValue($idCompany);
        $idUser = $user->getUserId();
        $data = [];
        $userHelper = new UsersHelper();

        if(!$billingAddress){
            $err_mes = [
                'code' => 'error',
                'message' => 'INVALID_PROFILE_ADDRESS'
            ];
            $data['messages'][] = $err_mes;

            return $data;
        }

        $checkMessage = $this->validateAddressData($billingAddress, 'billingAddress');
        if(!empty($checkMessage)){
            return $checkMessage;
        }

        $idAddress = isset($billingAddress->id) ? $billingAddress->id : 'null';

        $sql = "INSERT INTO ".TABLES['billing_information']." (id, idUser, idCountry, firstName, lastName, invoiceMail, city, detailedAddress, zip)
                VALUES(".$idAddress.",
                    ".$idUser.",
                    ".$billingAddress->idCountrySelected.",
                    '".$billingAddress->firstName."',
                    '".$billingAddress->lastName."',
                    '".$billingAddress->invoiceMail."',
                    '".$billingAddress->city."',
                    '".$billingAddress->detailedAddress."',
                    '".$billingAddress->zipCode."')
                ON DUPLICATE KEY UPDATE
                    idCountry= VALUES(idCountry),
                    firstName=VALUES(firstName),
                    lastName=VALUES(lastName),
                    invoiceMail=VALUES(invoiceMail),
                    city= VALUES(city),
                    detailedAddress=VALUES(detailedAddress),
                    zip=VALUES(zip)";

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

        if($database->affectedRows()) {
            $mes = [
                'code' => 'success',
                'message' => 'BILLING_ADDRESS_UPDATED'
            ];
            $data['messages'][] = $mes;
        }else{
            $mes = [
                'code' => 'warning',
                'message' => 'BILLING_ADDRESS_NOT_CHANGED'
            ];
            $data['messages'][] = $mes;
        }

        return $data;
    }
}
