<?php

/**
 * @package: EGPS - Easy Sell for Google Photo
 */

 if(!defined('ABSPATH')){
    exit; // Exit if accessed directly
}


class EgpsAlbums{

    /**
     * ----------------------------------------------
     * ALBUM AND PHOTO REMOVAL FUNCITONS ARE DISABLED
     * ----------------------------------------------
     * Do NOT delete album or photo from Google Photos. If the photo was purchased already,
     * the buyer wont be able to download it!
     * Instead, use button for Hide or Show albums or photos in EGPS admin panel
     */

    // button 3. (Import photos)
    public static function egps_download_images($type = "albums", $need_pbar = false){
        $photos_array = EgpsDatabase::egps_get_table_rows_where('egps_download', 'egps_type', $type);

        if(count($photos_array) != 0){
            Egps::egps_multiple_download($photos_array, $need_pbar);

        }else{
            //progress bar set to 100% if no files to download
            $myfile = fopen(__DIR__ . '/progress.json', "w") or die("Unable to open file!");
            $txt = json_encode(array(
                'percentComplete' => 100,
                'albumId' => 0
            ));
            fwrite($myfile, $txt);
            fclose($myfile);
            
        }
    }

    // button 1. (Sync albums)
    public static function egps_process_google_albums($nextPageToken){
        global $wpdb;

        $url = 'https://photoslibrary.googleapis.com/v1/albums';

        $query_args = [
            'access_token' => EGPS_TOKEN,
            'pageSize' => 50, //max 50 allowed
            'pageToken' => $nextPageToken
        ];
        $url = add_query_arg($query_args, $url);
        $response = wp_remote_request($url, ['sslverify' => false]);


        if (!is_wp_error($response) && $response['response']['code'] == 200) {

            $json_albums = json_decode($response['body']);

            $tablename = 'egps_albums';

            foreach ($json_albums->albums as $album_array){
                $db_array = array();

                foreach($album_array as $key => $val){
                    $db_array['egps_' . $key] = $val;
                }
                // IMPORTANT: sign item for delete 0. after function finished running, albums not containing 0 value will be deleted
                // This variable marks which albums to keep.
                $db_array['egps_item_for_delete'] = '0';

                /**
                 * Download album cover images directly
                 * NOT effective for large number of albums
                 * Instead, save downloadable image id into DB, and download it later
                 * Skip this if the photo is already downloaded before.
                 */
                $dwnld_array = [
                    'egps_id' => $db_array['egps_id'],
                    'egps_url' => $db_array['egps_coverPhotoBaseUrl'],
                    'egps_type' => 'albums'
                ];
                $album_changes_array = [
                    "egps_id" => $db_array["egps_id"],
                    "egps_type" => "album",
                    "egps_mediaItemsCount" => $db_array["egps_mediaItemsCount"],
                    "egps_url" => $db_array["egps_id"] //just for saving database space, id is shorter than the complete url: $db_array['egps_coverPhotoBaseUrl']
                ];

                
                $myrow = EgpsDatabase::egps_get_row('egps_albums', 'egps_id', $db_array['egps_id']);

                if($myrow == null){
                    //new albums set automatically to visible
                    $db_array['egps_album_show'] = 'y';
                    $db_array['egps_exclusiveCount'] = '0';
                    $db_array['time'] = date('Y-m-d');
                    $db_array['egps_updated'] = date('Y-m-d');
                    $db_array['egps_album_slug'] = Egps::egps_title_to_url($db_array['egps_title']);

                    //downloadable cover photo save to database for later download
                    EgpsDatabase::egps_insert_to_db_if_not_exists('egps_download', $dwnld_array);
                    //album data to database
                    EgpsDatabase::egps_insert_to_db($tablename, $db_array);

                    //save album into database for further album photos downloading {for egps_sync_albums()}
                    EgpsDatabase::egps_insert_to_db_if_not_exists('egps_albumchanges', $album_changes_array);

                }else{
                    //already in database
                    $where_array = array('egps_id' => $db_array['egps_id']);

                    //if album already exist, keeping the previously set up visibility
                    $db_array['egps_album_show'] = $myrow->egps_album_show;
                    $db_array['egps_exclusiveCount'] = $myrow->egps_exclusiveCount;
                    $db_array['egps_updated'] = date('Y-m-d');

                    // save album changes, most importantly, set sign to delete to 0
                    EgpsDatabase::egps_update_db_table($tablename, $db_array, $where_array);

                    //if album data already exists in database, check if were any changes in items count
                    //if changes happened, save album id to later photos update
                    if($db_array['egps_mediaItemsCount'] != $myrow->egps_mediaItemsCount){

                        //only process active albums
                        if($myrow->egps_album_show == "y") {
                            //save album into database for further album photos downloading {for egps_sync_albums()}
                            EgpsDatabase::egps_insert_to_db_if_not_exists('egps_albumchanges', $album_changes_array);
                        }
                    }

                }
                
            }
            

            //if too many albums created in Google Photos, call recursively
            if(isset($json_albums->nextPageToken)){
                //if the user has more than 50 albums, we call a function recursively
                EgpsAlbums::egps_process_google_albums($json_albums->nextPageToken);
            }

            return;

        }else{
            echo "Encountered error: <br/>";
            Egps::egps_vardump($response);
        }

        return null;
    }
    
    public static function egps_process_google_photos($album_id, $nextPageToken, $actual_item_no, $itemcount){
        global $wpdb;
        $wpdb->show_errors();

        $curl_args = [
            'contentType' => "application/json",
            'headers' => ['Authorization' => "Bearer " . get_option('egps_options')['google_access_token']],
            'method' => 'POST',
            'body' => [
                'albumId' => $album_id,
                'pageSize' => 100,
                'pageToken' => $nextPageToken
            ],
            'cookies' => [],
        ];

        $response = wp_remote_request('https://photoslibrary.googleapis.com/v1/mediaItems:search', $curl_args);

        if (!is_wp_error($response)) {

            $photoalbum = json_decode($response['body']);
            
            $tablename = 'egps_photos';

            $db_array = array();

            foreach($photoalbum->mediaItems as $item){

                $db_array['egps_id'] = $item->id;
                $db_array['egps_album_id'] = $album_id;
                $db_array['egps_productUrl'] = $item->productUrl;
                $db_array['egps_baseUrl'] = $item->baseUrl;
                $db_array['egps_mediaMetadata'] = json_encode($item->mediaMetadata, true);

                $db_array['egps_mediaCamera'] = $item->mediaMetadata->photo->cameraMake . ' ' . $item->mediaMetadata->photo->cameraModel;
                $db_array['egps_mediaCameraUrl'] = str_replace( " ", "-", strtolower( $db_array['egps_mediaCamera'] ) );
                $db_array['egps_mediaSize'] = round($item->mediaMetadata->width * $item->mediaMetadata->height / 1000000, 1);
                $db_array['egps_purchase_count'] = "0";
                $db_array['egps_photo_show'] = "y";

                $db_array['egps_description'] = Egps::egps_stripAccents($item->description);
                //update tag cloud
                EgpsDatabase::egps_update_tag_cloud( Egps::egps_stripAccents($item->description));
                
                $db_array['egps_item_for_delete'] = '0';
                $db_array['egps_exclusive'] = 0;
                $db_array['egps_created'] = $item->mediaMetadata->creationTime;
                $db_array['egps_updated'] = Egps::egps_datenow();

                $myrow = EgpsDatabase::egps_get_row('egps_photos', 'egps_productUrl', $db_array['egps_productUrl']);

                if($myrow == null){ //if photo new in album on Google Photos

                    $dwnld_array = [
                        'egps_id' => $db_array['egps_id'],
                        'egps_url' => $db_array['egps_baseUrl'],
                        'egps_type' => 'photos'
                    ];
                    EgpsDatabase::egps_insert_to_db_if_not_exists('egps_download', $dwnld_array);
                    EgpsDatabase::egps_insert_to_db($tablename, $db_array);

                }else if($myrow->egps_album_id != $album_id) {

                    EgpsDatabase::egps_insert_to_db($tablename, $db_array);

                }else{

                    /**
                     * DISABLED
                     * If photo is already in the EGPS database DO NOT UPDATE records.
                     * Updating will reset: purchase count, exclusive sign and show sign too.
                     */
                    //$where_array = array('egps_id' => $db_array['egps_id']);
                    //EgpsDatabase::egps_update_db_table($tablename, $db_array, $where_array);
                }

            }

            if(isset($photoalbum->nextPageToken)){
                //if the album contains more than 100 images, we call a function recursively
                EgpsAlbums::egps_process_google_photos($album_id, $photoalbum->nextPageToken, $actual_item_no, $itemcount);
            }

        }else{
            //error
            Egps::egps_vardump($response);
        }
        
    }

    // button 2. (Sync photos - meta)
    public static function egps_sync_albums(){

        //If the album removed form Google Photos this will remove it from database.
        /*  DISABLED -> Do NOT delete album or photo from Google Photos. 
            If the photo was purchased already,
            the buyer wont be able to download it!
            Instead, use Hide/Show album in EGPS admin panel
            //EgpsAlbums::egps_delete_signed_albums();
        */


        $db_album = EgpsDatabase::egps_get_table_rows("egps_albumchanges");

        $sum_items = count($db_album);
        $act_item = 0;

        //ob_flush();
        //flush();

        if($sum_items != 0){
            foreach($db_album as $album){

                // IMPORTANT: sign for delete all photos in album by album id. 
                /**
                 * DISABLED
                 */
                /*
                EgpsDatabase::egps_update_db_table(
                    "egps_photos", 
                    array('egps_item_for_delete' => 1), 
                    array('egps_album_id' => $album->egps_id) 
                );
                */

                $act_item++;

                EgpsAlbums::egps_process_google_photos($album->egps_id, '', 0, $album->egps_mediaItemsCount);

                //remove photos if they were deleted from album on Google Photos
                /**
                 * DISABLED
                 */
                /*
                if($album->egps_id != null){
                    EgpsAlbums::egps_delete_signed_photos_by_album_id($album->egps_id);
                }
                */

                //delete record
                EgpsDatabase::egps_delete_record("egps_albumchanges", $album->id);

                //progress bar value
                $myfile = fopen(__DIR__ . '/progress.json', "w") or die("Unable to open file!");
                $txt = json_encode(array(
                    'percentComplete' => round($act_item / $sum_items * 100),
                    'albumId' => $album->id
                ));
                fwrite($myfile, $txt);
                fclose($myfile);

            }
            
        }else{

            //progress bar value if no sync needed
            $myfile = fopen(__DIR__ . '/progress.json', "w") or die("Unable to open file!");
            $txt = json_encode(array(
                'percentComplete' => 100,
                'albumId' => 0
            ));
            fwrite($myfile, $txt);
            fclose($myfile);
        }

    }



    public static function egps_show_photo_count($album_id = "", $type = "egps_mediaItemsCount"){
        //egps_mediaItemsCount or egps_exclusiveCount

        global $wpdb;
        $wpdb->show_errors();

        if($album_id == ""){
            $query = $wpdb->prepare(
                "SELECT sum(%i) FROM ".$wpdb->prefix."egps_albums ", 
                $type
            );
            $ret_val = $wpdb->get_var($query);

        }else{
            $query = $wpdb->prepare(
                "SELECT sum(%i) FROM ".$wpdb->prefix."egps_albums WHERE egps_id = %s ", 
                $type, $album_id
            );
            $ret_val = $wpdb->get_var($query);
        }

        return $ret_val;
    }



    public static function egps_change_album_show($album_id, $visible = "y"){
        global $wpdb;
        
        $where_array = array('id' => substr($album_id, 10)); //cut off 'egps_show_' from id string
        $data_array = array('egps_album_show' => $visible);

        EgpsDatabase::egps_update_db_table("egps_albums", $data_array, $where_array);

    }

    public static function egps_change_photo_show($photo_id, $visible = "y"){
        global $wpdb;
        
        $where_array = array('egps_id' => substr($photo_id, 16)); //cut off 'egps_show_photo_' from id string
        $data_array = array('egps_photo_show' => $visible);

        EgpsDatabase::egps_update_db_table("egps_photos", $data_array, $where_array);

    }

    public static function egps_set_photo_exclusive($photo_id, $purchase_id = ""){
        global $wpdb;

        // sign the photo itself
        $tn_photos = 'egps_photos';
        $data = ["egps_exclusive"   => "1"];
        $where = ["egps_id"         => $photo_id];
        EgpsDatabase::egps_update_db_table($tn_photos, $data, $where);

        // add to exclusive table if not already exists
        $tn_insert = 'egps_exclusive';
        $data_insert = [
            "egps_photo_id"     => $photo_id,
            "egps_purchase_id"  => $purchase_id,
            'time'              => Egps::egps_datenow()
        ];
        if(EgpsDatabase::egps_get_row($tn_insert, 'egps_photo_id', $photo_id) == null){
            
            EgpsDatabase::egps_insert_to_db($tn_insert, $data_insert);

        }
        
        // go through albums list and refresh exclusive count
        $tn_albums = 'egps_albums';
        
        $albums = EgpsDatabase::egps_get_table_rows($tn_albums);

        if($albums != null){
            foreach($albums as $al){
                $new_count = EgpsDatabase::egps_count_table_rows_where_exclusive(
                    $tn_photos, $al->egps_id
                );

                $data_array = ['egps_exclusiveCount' => $new_count];
                $where_array = ['egps_id' => $al->egps_id];

                EgpsDatabase::egps_update_db_table($tn_albums, $data_array, $where_array);
            }
        }
       
    
    }

    public static function egps_is_photo_exclusive($photo_id){
        global $wpdb;
        $wpdb->show_errors();

        $table_name = $wpdb->prefix . "egps_exclusive";

        try{
            
            $query = $wpdb->prepare(
                "SELECT * FROM $table_name WHERE egps_photo_id = %s",
                $photo_id
            );
            $ret_val = $wpdb->get_row($query);
            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
            return null;
        }
        return null;
    }

    public static function egps_get_random_albumcover($album_id){
        global $wpdb;
        $wpdb->show_errors();

        $tn_photos = $wpdb->prefix . "egps_photos";

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_album_id  
                FROM $tn_photos 
                WHERE egps_album_id = %s 
                ORDER BY rand() 
                LIMIT 1",
                $album_id
            );
            $ret_val = $wpdb->get_results($query);

            return $ret_val[0]->egps_id;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }


    public static function egps_get_active_albums($field = 'id', $asc = 'ASC', $getfields = "rest"){
        global $wpdb;
        $wpdb->show_errors();

        $options = get_option('egps_sitedesign');

        $tablename = $wpdb->prefix . "egps_albums";

        try{

            switch($getfields){
                case "all_data":
                    $fieldlist = "*";
                    break;

                case "rest":
                    $fieldlist = "id, egps_id, egps_title, egps_album_slug, egps_mediaItemsCount, 
                    egps_exclusiveCount";
                    break;

                case "rest_order":
                    $fieldlist = "id, egps_id, egps_title, egps_album_slug, egps_mediaItemsCount, 
                    egps_exclusiveCount, egps_updated";
                    break;

                default:
                    $fieldlist = "id, egps_id, egps_title, egps_album_slug, egps_mediaItemsCount, 
                    egps_exclusiveCount";
            }

            switch($field){
                case "egps_title":
                    $order_by = "egps_title";
                    break;
                    
                case "latest":
                    $order_by = 'egps_updated';
                    break;
                
                case "trending":
                    $order_by = 'cast(egps_mediaItemsCount as unsigned)';
                    break;
    
                case "random":
                    $order_by = 'rand()';
                    break;
    
                default:
                    $order_by = 'cast(egps_mediaItemsCount as unsigned)';
            }

            switch($asc){
                case "DESC":
                    $orderasc = "DESC";
                    break;

                default:
                    $orderasc = "ASC";
            }

            $query = $wpdb->prepare(
                "SELECT $fieldlist 
                FROM $tablename 
                WHERE egps_album_show = 'y' 
                ORDER BY $order_by $orderasc",
                $field
            );

            $ret_val = $wpdb->get_results($query);

            foreach($ret_val as $rv){
                if( (isset($options['wp_randomalbumcovers_on']) && $options['wp_randomalbumcovers_on'] == 'on') ){
                    
                    $new_albumcover = EgpsAlbums::egps_get_random_albumcover($rv->egps_id);

                    if($new_albumcover != null){
                        $rv->egps_album_cover = $new_albumcover;
                        $rv->egps_rd_cover = true;
                    }else{
                        $rv->egps_album_cover = $rv->egps_id;
                        $rv->egps_rd_cover = false;
                    }

                }else{

                    $rv->egps_album_cover = $rv->egps_id;

                }
         
            }

            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_album_photos($album_id){
        global $wpdb;
        $wpdb->show_errors();

        $tn_albums = $wpdb->prefix . "egps_albums";
        $tn_photos = $wpdb->prefix . "egps_photos";

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_mediaMetadata
                FROM $tn_photos 
                WHERE egps_exclusive = '0' 
                    AND egps_album_id IN (SELECT egps_id FROM $tn_albums 
                        WHERE egps_album_slug = %s
                        AND egps_album_show = 'y') 
                ORDER BY egps_created DESC;",
                $album_id
            );
            $ret_val = $wpdb->get_results($query);

            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_album_photos_order($album_id, $order){
        global $wpdb;
        $wpdb->show_errors();

        $tn_albums = $wpdb->prefix . "egps_albums";
        $tn_photos = $wpdb->prefix . "egps_photos";

        switch($order){
            case "latest":
                $order_by = 'egps_created';
                break;
            
            case "trending":
                $order_by = 'egps_purchase_count';
                break;

            case "random":
                $order_by = 'rand()';
                break;

            default:
                $order_by = 'egps_created';
        }
        

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_mediaMetadata, egps_purchase_count 
                FROM $tn_photos 
                WHERE egps_exclusive = '0' 
                    AND egps_photo_show = 'y' 
                    AND egps_album_id IN (SELECT egps_id FROM $tn_albums 
                        WHERE egps_album_slug = %s 
                        AND egps_album_show = 'y') 
                ORDER BY $order_by DESC;",
                $album_id
            );

            $ret_val = $wpdb->get_results($query);

            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_one_photo($photo_id){
        global $wpdb;
        $wpdb->show_errors();

        $tn = $wpdb->prefix . "egps_photos";

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_mediaMetadata, egps_mediaCamera, egps_mediaCameraUrl, egps_description 
                FROM $tn 
                WHERE id = %s 
                LIMIT 1;",
                $photo_id
            );

            $ret_val = $wpdb->get_results($query);

            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_tagsearch_photos($tagname, $order='id'){
        global $wpdb;
        $wpdb->show_errors();

        $tn = $wpdb->prefix . "egps_photos";
        $tn_albums = $wpdb->prefix . "egps_albums";
        //$tagname = mysql_real_escape_string($tagname);

        switch($order){
            case "latest":
                $order_by = 'egps_created';
                break;
            
            case "trending":
                $order_by = 'egps_purchase_count';
                break;

            case "random":
                $order_by = 'rand()';
                break;

            default:
                $order_by = 'id';
        }

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_mediaMetadata, egps_description 
                FROM $tn 
                WHERE egps_exclusive = '0' 
                    AND egps_album_id IN (SELECT egps_id FROM $tn_albums WHERE egps_album_show = 'y') 
                    AND egps_description LIKE %s 
                GROUP BY egps_id
                ORDER BY $order_by DESC",
                '%'.$tagname.'%'
            );

            $ret_val = $wpdb->get_results($query);

            return ( !empty($ret_val) ) ? $ret_val : null;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_camerasearch_photos($tagname, $order = 'id'){
        global $wpdb;
        $wpdb->show_errors();

        $tn = $wpdb->prefix . "egps_photos";
        $tn_albums = $wpdb->prefix . "egps_albums";

        switch($order){
            case "latest":
                $order_by = 'egps_created';
                break;
            
            case "trending":
                $order_by = 'egps_purchase_count';
                break;

            case "random":
                $order_by = 'rand()';
                break;

            default:
                $order_by = 'id';
        }

        try{

            $query = $wpdb->prepare(
                "SELECT id, egps_id, egps_mediaMetadata, egps_mediaCamera, egps_mediaCameraUrl, egps_description 
                FROM $tn 
                WHERE egps_exclusive = '0' 
                    AND egps_album_id IN (SELECT egps_id FROM $tn_albums WHERE egps_album_show = 'y') 
                    AND egps_mediaCameraUrl LIKE %s 
                GROUP BY egps_id 
                ORDER BY $order_by DESC",
                '%'.$tagname.'%'
            );

            $ret_val = $wpdb->get_results($query);
            return ( !empty($ret_val) ) ? $ret_val : null;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }

    public static function egps_get_camera_cloud($camera = ""){
        global $wpdb;
        $wpdb->show_errors();

        $tn = $wpdb->prefix . "egps_photos";

        try{

            $query = $wpdb->prepare(
                "SELECT DISTINCT egps_mediaCamera, egps_mediaCameraUrl 
                FROM %i 
                ORDER BY egps_mediaCamera",
                $tn
            );
            $ret_val = $wpdb->get_results($query);

            return $ret_val;

        }catch (Error $error){
            Egps::egps_vardump($error);
        }
        return null;
    }


    /*
        DISABLED
        Do NOT delete photos or albums from Google Photos, set visibility in EGPS admi panel!
        IMPORTANT! If the photo was purchased already, the buyer wont be able to download it!
    */
    public static function egps_delete_signed_albums(){
        global $wpdb;
        $wpdb->show_errors();

        $table_name = $wpdb->prefix . "egps_albums";

        try{

            //$wpdb->query("DELETE FROM $table_name WHERE egps_item_for_delete != '0' ");

        }catch (Error $err){
            Egps::egps_vardump($err);
        }

        return;

    }

    /*
    //  only used for deleting photos from database if removed from album on Google Photos
        DISABLED
        Do NOT delete photos or albums from Google Photos, set visibility in EGPS admi panel!
        IMPORTANT! If the photo was purchased already, the buyer wont be able to download it!
    */
    public static function egps_delete_signed_photos_by_album_id($album_id){
        global $wpdb;
        $wpdb->show_errors();

        $table_name = $wpdb->prefix . "egps_photos";

        try{
            /*
            $query = $wpdb->prepare(
                "DELETE FROM $table_name 
                WHERE egps_album_id = %s AND egps_item_for_delete != '0' ",
                $album_id
            );

            $wpdb->query($query);
            */

        }catch (Error $err){
            Egps::egps_vardump($err);
        }

        return;

    }

    public static function egps_makeProgress($percent) {
        /*
        $myfile = fopen(__DIR__ . '/progress.json', "w") or die("Unable to open file!");
        $txt = json_encode(array('percentComplete' => round($percent)));
        fwrite($myfile, $txt);
        fclose($myfile);
        */
    }


}