<?php
/**
 * UserProfileModel
 * Handles all the Data for presenting a user that offers stuff.
 */
class UserProfileModel
{
    public static function checkOwnership($profile_id)
    {
        if (Session::userIsAdmin()) {
            return true;
        } else {
            $prefix = Config::get('DB_PREFIX');
            $database = DatabaseFactory::getFactory()->getConnection();
            $sql = "SELECT P.user_id
                    FROM ".$prefix."profiles AS P
                    WHERE P.id = :profile_id
                    LIMIT 1";
            $query = $database->prepare($sql);
            $query->bindParam(':profile_id', $profile_id, PDO::PARAM_INT);
            $query->execute();
            if ($query->rowCount() == 1) {
                $profile = $query->fetch();
                if ($profile->user_id == Session::get('user_id')) {
                    return true;
                } else {
                    Session::add('feedback_negative',
                            Text::get('FEEDBACK_PROFILE_INSUFFICIENT_PRIVILEGES'));
                    Redirect::to('profiles/view/'.$profile_id);
                    exit();
                }
            } else {
                Session::add('feedback_negative',
                        Text::get('FEEDBACK_PROFILE_INSUFFICIENT_PRIVILEGES'));
                Redirect::to('profiles/view/'.$profile_id);
                exit();
            }
        }
    }

    public static function isOwner($profile_id)
    {
        if (Session::userIsAdmin()) {
            return true;
        } else {
            $prefix = Config::get('DB_PREFIX');
            $database = DatabaseFactory::getFactory()->getConnection();
            $sql = "SELECT P.user_id
                    FROM ".$prefix."profiles AS P
                    WHERE P.id = :profile_id
                    LIMIT 1";
            $query = $database->prepare($sql);
            $query->bindParam(':profile_id',   $profile_id,          PDO::PARAM_INT);
            $query->execute();
            if ($query->rowCount() == 1) {
                $profile = $query->fetch();
                if ($profile->user_id == Session::get('user_id')) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    public static function featureProfile($profile_id)
    {
        $profile = self::getUserProfile($profile_id);
        if ($profile->admin_featured == 1) {
            $feature = 0;
        } else {
            $feature = 1;
        }
        if (self::updateUserProfile('admin_featured', $feature, $profile_id)) {
            Session::add('feedback_positive',
                            Text::get('FEEDBACK_PROFILE_FEATURED'));
        } else {
            Session::add('feedback_negative',
                            Text::get('FEEDBACK_PROFILE_FEATURE_FAILED'));
        }
    }

    public static function featureOtherProfile($profile_id)
    {
        $profile = self::getUserProfile($profile_id);
        if ($profile->other_featured == 1) {
            $feature = 0;
        } else {
            $feature = 1;
        }
        if (self::updateUserProfile('other_featured', $feature, $profile_id)) {
            Session::add('feedback_positive',
                            Text::get('FEEDBACK_PROFILE_FEATURED'));
        } else {
            Session::add('feedback_negative',
                            Text::get('FEEDBACK_PROFILE_FEATURE_FAILED'));
        }
    }

    /**
     * @param int $profile_id The profile's id
     *
     * @return mixed The Details about a single user on the platform
     */
    public static function getUserProfile($profile_id)
    {
        $profile_id = (int) $profile_id;
        if (!is_int($profile_id)) {
            return false;
        }
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "SELECT P.id                             AS id,
                       P.slug                           AS slug,
                       P.company_name                   AS company_name,
                       P.company_claim                  AS company_claim,
                       P.company_short_info             AS company_short_info,
                       P.company_info                   AS company_info,
                       P.company_opening_hours          AS company_opening_hours,
                       P.company_logo_path              AS company_logo_path,
                       P.company_header_path            AS company_header_path,
                       P.company_contact_person         AS company_contact_person,
                       P.company_phone                  AS company_phone,
                       P.company_fax                    AS company_fax,
                       P.company_email                  AS company_email,
                       P.company_website                AS company_website,
                       P.company_address_street         AS company_address_street,
                       P.company_address_street_number  AS company_address_street_number,
                       P.company_address_zipcode        AS company_address_zipcode,
                       P.company_address_city           AS company_address_city,
                       P.company_address_state          AS company_address_state,
                       P.company_address_country        AS company_address_country,
                       P.user_id                        AS user_id,
                       P.admin_featured                 AS admin_featured,
                       P.other_featured                 AS other_featured,
                       P.created                        AS created,
                       P.modified                       AS modified
                FROM ".$prefix."profiles                AS P
                WHERE P.id = :profile_id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id', $profile_id, PDO::PARAM_INT);
        $query->execute();

        $details = $query->fetch();

        if ($query->rowCount() == 0) {
            Session::add('feedback_negative',
                         Text::get('FEEDBACK_PROFILE_DOESNT_EXIST'));
            return false;
        }

        return $details;
    }

    public static function getProfileIdBySlug($profile_slug)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "SELECT id
                FROM ".$prefix."profiles
                WHERE slug = :profile_slug
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_slug', $profile_slug, PDO::PARAM_STR);
        if ($query->execute() && $query->rowCount() > 0)
        {
            return $query->fetch()->id;
        } else {
            return false;
        }
    }

    public static function checkExistenceOfUserProfileByUserId($user_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT id
                FROM ".$prefix."profiles
                WHERE user_id = :user_id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':user_id', $user_id, PDO::PARAM_INT);
        $query->execute();

        if ($query->rowCount() == 0) {
            self::createUserProfile($user_id);
        }
    }

    public static function getUserProfilesByUserId($user_id)
    {
        self::checkExistenceOfUserProfileByUserId($user_id);

        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "SELECT P.id                             AS id,
                       P.slug                           AS slug,
                       P.company_name                   AS company_name,
                       P.company_claim                  AS company_claim,
                       P.company_short_info             AS company_short_info,
                       P.company_logo_path              AS company_logo_path,
                       P.company_header_path            AS company_header_path,
                       P.created                        AS created,
                       P.modified                       AS modified
                FROM ".$prefix."profiles                AS P
                WHERE P.user_id = :user_id
                LIMIT 10";
        $query = $database->prepare($sql);
        $query->bindParam(':user_id', $user_id, PDO::PARAM_INT);
        $query->execute();

        $profiles = array();

        $i = 0;
        foreach ($query->fetchAll() as $profile) {
            $profiles[$i]                       = new stdClass();
            $profiles[$i]->id                   = $profile->id;
            $profiles[$i]->slug                 = $profile->slug;
            $profiles[$i]->company_name         = $profile->company_name;
            $profiles[$i]->company_claim        = $profile->company_claim;
            $profiles[$i]->company_short_info   = $profile->company_short_info;
            $profiles[$i]->company_logo_path    = $profile->company_logo_path;
            $profiles[$i]->company_header_path  = $profile->company_header_path;
            $profiles[$i]->created              = $profile->created;
            $profiles[$i]->modified             = $profile->modified;
            $i++;
        }

        return $profiles;
    }

    /**
     * @param array $args Arguments like the number of Profiles to get.
     * Gets an array that contains all profiles.
     * The array's keys are the detail ids.
     * Each array element is an object, containing a specific profile's data.
     *
     * @return array All the profiles
     */
    public static function getProfiles($args)
    {
        DatabaseArgs::setArgs($args, 'profiles');
        $start = DatabaseArgs::getStart();
        $limit = DatabaseArgs::getHowMany();
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "SELECT SQL_CALC_FOUND_ROWS
                       P.id                      AS id,
                       P.slug                    AS slug,
                       P.company_name            AS company_name,
                       P.company_claim           AS company_claim,
                       P.company_logo_path       AS company_logo_path,
                       P.company_header_path     AS company_header_path,
                       P.company_address_zipcode AS company_zipcode,
                       P.company_address_city    AS company_city,
                       P.user_id                 AS user_id,
                       P.admin_featured          AS admin_featured,
                       P.other_featured          AS other_featured,
                       P.created                 AS created,
                       P.modified                AS modified
                FROM ".$prefix."profiles         AS P
                ".DatabaseArgs::getWhereStmt()."
                ORDER BY ".DatabaseArgs::getOrderBy()."
                LIMIT :start,:limit";
        $query = $database->prepare($sql);
        $query->bindParam(':start', $start,   PDO::PARAM_INT);
        $query->bindParam(':limit', $limit,   PDO::PARAM_INT);
        $query->execute();

        $profiles = array();

        $profiles['number'] = $database->query("SELECT FOUND_ROWS()")->fetchColumn();
        $i = 0;
        foreach ($query->fetchAll() as $profile) {
            $profiles['data'][$i]                 = new stdClass();
            $profiles['data'][$i]->id             = $profile->id;
            $profiles['data'][$i]->slug           = $profile->slug;
            $profiles['data'][$i]->company_name   = $profile->company_name;
            $profiles['data'][$i]->company_claim  = $profile->company_claim;
            $profiles['data'][$i]->logo_path      = $profile->company_logo_path;
            $profiles['data'][$i]->header_path    = $profile->company_header_path;
            $profiles['data'][$i]->zipcode        = $profile->company_zipcode;
            $profiles['data'][$i]->city           = $profile->company_city;
            $profiles['data'][$i]->user_id        = $profile->user_id;
            $profiles['data'][$i]->admin_featured = $profile->admin_featured;
            $profiles['data'][$i]->other_featured = $profile->other_featured;
            $profiles['data'][$i]->created        = $profile->created;
            $profiles['data'][$i]->modified       = $profile->modified;
            $i++;
        }

        return $profiles;
    }

    public static function checkCompletion($profile_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT P.id AS id
                FROM ".$prefix."profiles AS P
                WHERE P.id = :profile_id
                  AND company_name IS NOT NULL
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id',     $profile_id,     PDO::PARAM_INT);
        $query->execute();
        if ($query->rowCount() == 1) {
            return true;
        } else {
            Session::add('feedback_negative',
                            Text::get('FEEDBACK_PROFILE_NOT_COMPLETE'));
            Redirect::to('profiles/edit/'.$profile_id);
            exit();
        }
    }

    public static function createUserProfile($user_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "INSERT INTO ".$prefix."profiles
                (user_id,created,modified) VALUES (:user_id,NOW(),NOW())";
        $query = $database->prepare($sql);
        $query->bindParam(':user_id', $user_id, PDO::PARAM_INT);
        $query->execute();
        if ($query->rowCount() == 1) {
            return true;
        } else {
            return false;
        }
    }

    public static function saveProfile($profile_id)
    {
        $values = array('slug'                          => 'slug',
                        'companyName'                   => 'company_name',
                        'companyClaim'                  => 'company_claim',
                        'companyShortInfo'              => 'company_short_info',
                        'companyInfo'                   => 'company_info',
                        'companyOpeningHours'           => 'company_opening_hours',
                        'companyContactPerson'          => 'company_contact_person',
                        'companyPhone'                  => 'company_phone',
                        'companyFax'                    => 'company_fax',
                        'companyEmail'                  => 'company_email',
                        'companyWebsite'                => 'company_website',
                        'companyAddressStreet'          => 'company_address_street',
                        'companyAddressStreetNumber'    => 'company_address_street_number',
                        'companyAddressZipcode'         => 'company_address_zipcode',
                        'companyAddressCity'            => 'company_address_city',
                        'companyAddressState'           => 'company_address_state',
                        'companyAddressCountry'         => 'company_address_country');
        $i = 0; $saved = 0;
        foreach($values as $postName => $DBName) {
            switch ($postName) {
                case 'companyAddressZipcode':
                    $newZipcode = Request::post($postName, true);
                    $oldZipcode = self::getUserProfile($profile_id)->company_address_zipcode;
                    if ($newZipcode != $oldZipcode) {
                        OfferModel::updateOfferZipcodes($profile_id,$newZipcode);
                    }
                    break;
                case 'slug':
                    $slug = Helper::slugify(Request::post('companyName', true));
                    $slug_id = UserProfileModel::getProfileIdBySlug($slug);
                    if ($slug_id != false && $slug_id != $profile_id) {
                        $slug .= "-".$profile_id;
                    }
                    if (self::updateUserProfile($DBName,
                                                $slug,
                                                $profile_id)) {
                        $saved++;
                    }
                    $skip = true;
                    break;
                default:
                    $skip = false;
                    break;
            }
            if (!$skip) {
                if (self::updateUserProfile($DBName,
                                            Request::post($postName, true),
                                            $profile_id)) {
                    $saved++;
                }
            }
            $i++;
        }
        if ($saved == $i) {
            Session::add('feedback_positive',
                         Text::get('FEEDBACK_PROFILE_UPDATE_SUCCESSFUL'));
        } else {
            Session::add('feedback_negative',
                         Text::get('FEEDBACK_PROFILE_UPDATE_FAILED'));
        }
    }

    public static function saveImage($profile_id,$field,$imagePath)
    {
        return self::updateUserProfile($field,$imagePath,$profile_id);
    }

    public static function updateUserProfile($db_name,$value,$profile_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "UPDATE ".$prefix."profiles
                SET ".$db_name." = :value,
                    modified = NOW()
                WHERE id = :profile_id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':value',         $value,             PDO::PARAM_STR);
        $query->bindParam(':profile_id',    $profile_id,        PDO::PARAM_INT);
        if ($query->execute()) {
            return true;
        } else {
            return false;
        }
    }

    public static function getNumber($type,$profile_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();

        $sql = "SELECT COUNT(id) AS number
                FROM ".$prefix."offers
                WHERE profile_id = :profile_id
                  AND type = :type
                  AND status > 0";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id',    $profile_id,        PDO::PARAM_INT);
        $query->bindParam(':type',          $type,              PDO::PARAM_INT);
        $query->execute();
        $offer = $query->fetch();
        return $offer->number;
    }

    public static function deleteProfile($profile_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT user_id,
                       company_logo_path,
                       company_header_path
                FROM ".$prefix."profiles
                WHERE id = :profile_id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id',    $profile_id,        PDO::PARAM_INT);
        $query->execute();
        $profile = $query->fetch();

        $img = array();
        if ($profile->company_logo_path != null) {
            $img['logo'] = $profile->company_logo_path;
        }
        if ($profile->company_header_path != null) {
            $img['header'] = $profile->company_header_path;
        }
        UploadModel::deleteImages($img, false);

        // get ids of offers and requests of profile for deletion
        $offers = self::getOffersAndRequestsOfProfile($profile_id);
        $total = 0; $success = 0;
        foreach ($offers as $offer_id) {
            $total++;
            if (OfferModel::deleteOffer($offer_id)) {
                $success++;
            }
        }
        if ($total == $success) {
            $offersDeleted = true;
        }

        $profiles = self::getUserProfilesByUserId($profile->user_id);
        if (count($profiles) == 1) {
            UserModel::deleteUser($profile->user_id);
        }

        $sql = "DELETE
                FROM ".$prefix."profiles
                WHERE id = :profile_id
                LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id',    $profile_id,        PDO::PARAM_INT);
        if ($query->execute() && $query->rowCount() > 0 && $offersDeleted === true) {
            Session::add('feedback_positive',
                         Text::get('FEEDBACK_PROFILE_DELETION_SUCCESSFUL'));
        } else {
            Session::add('feedback_negative',
                         Text::get('FEEDBACK_PROFILE_DELETION_FAILED'));
        }
    }

    public static function getOffersAndRequestsOfProfile($profile_id)
    {
        $prefix = Config::get('DB_PREFIX');
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT id
                FROM ".$prefix."offers
                WHERE profile_id = :profile_id";
        $query = $database->prepare($sql);
        $query->bindParam(':profile_id',    $profile_id,        PDO::PARAM_INT);
        $query->execute();

        $offers = array();

        foreach ($query->fetchAll() as $offer) {
            $offers[] = $offer->id;
        }
        return $offers;
    }
}
