<?php

require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
if( !function_exists('get_plugin_data') ){
    require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}

class LinksgardenAPI
{
    // Lance les actions
    // Format de la requete : https://www.exemple.com/wp-json/lg/v1/API?apiKey=MonApiKey&action=MonAction
    public static function getAction(WP_REST_Request $request){

        $aActions = array(
            'lastId',                   // Retourne ID du dernier article
            'checkVersion',             // Retourne la version du plugin
            'nextId',                   // Retourne l'id du prochain article
            'postInfos',                // Retourne le titre et le contenu d'un article
            'url',                      // Retourne l'url' d'un article
            'categorie',                // Retourne la catégorie d'un article
            'title',                    // Retourne le titre d'un article
            'contenu',                  // Retourne le contenu d'un article
            'get_image_une',            // Retourne l'url de l'image a la une (thumbnail)
            'new_category',             // Crée une nouvelle catégorie - Retourne l'id de la catégorie crée
            'newpost',                  // Crée un nouvel article - Retourne l'id de l'article crée
            'update_post_content',      // Modifie le titre, le contenu, l'url et le thumbnail d'un article
            'delete_post',              // Supprime un article
            'up_image',                 // Upload une image - Retourne l'url de l'image upload
            'set_image_une',            // Poste une image d'entête à un article - Retourne un id
            'set_post_format',          // Change le format d'un post
            'delete_image',             // Supprime un media
            'get_cat_slug_by_id',       // Retourne le nom d'une catégorie
            'count_post',               // Retourne le nombre d'articles d'un blog
            'get_all_post',             // Retourne un tableau avec tous les id des articles du blog
            'get_post_id',              // Retourne l'id d'un article selon son url
            'change_url_meta_infos',    // Change les metadonnées d'un article via son url
            'get_all_category',         // Retourne un tableau de toutes les correspondances id / categories
            'remove_ownership'          // Désactive la propriété du site
        );

        if (in_array($request['action'], $aActions)){
            if (isset($request['apiKey'], $request['signature'])) {
                if (LinksgardenRest::isApiSecret($request['apiKey'], $request['signature'])) {
                    return self::{$request['action']}($request);
                }
                return self::api_error('Signature non valide');
            }
            return self::api_error('Clé API non valide');
        } else {
            return self::api_error('Action Inconnue');
        }
    }

    /*
     * Retourne ID du dernier article
     * Requête action=lastId
     */
    public static function lastId(WP_REST_Request $request){
        $arrayLastPostId = get_posts("numberposts=1&fields=ids");
        $lastPostId = $arrayLastPostId[0];
            return self::api_success($lastPostId);
    }

    /*
     * Retourne la version du plugin
     * Requête action=checkVersion
     */
    public static function checkVersion(WP_REST_Request $request){
        $plugin_info = get_plugin_data(LG_PLUGIN_FILE);
        return self::api_success($plugin_info['Version']);
    }

    /*
     * Retourne l'id du prochain article
     * Requête action=nextId ; positionId=IdArticle
     */
    public static function nextId(WP_REST_Request $request){
        // par défaut la position id 0 renvoi le dernier article
        if (isset($request["positionId"])) {
            $positionId = $request["positionId"];
            $arrayLastPostId = get_posts("numberposts=1&fields=ids");
            $lastPostId = $arrayLastPostId[0];
            while(true){
                $infos = get_post($positionId);
                if($infos->post_status == "publish" && $infos->post_type == "post"){
                    return self::api_success($positionId);
                }
                $positionId = $positionId+1;
                if($lastPostId < $positionId) {
                    return self::api_error("code 777"); // 777 veut dire derniere position atteinte
                }
            }
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne le titre et le contenu d'un article
     * Requête action=postInfos ; positionId=IdArticle
     */
    public static function postInfos(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            $infos = get_post($request['positionId']);
            if ($infos) {
                return self::api_success(array('titre' => $infos->post_title, 'contenu' => $infos->post_content));
            }
            return self::api_error('Id '.$request['positionId'].' inconnu');
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne l'url' d'un article
     * Requête action=url ; positionId=IdArticle
     */
    public static function url(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            return self::api_success(get_permalink($request["positionId"]));
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne la catégorie d'un article
     * Requête action=categorie ; positionId=IdArticle
     */
    public static function categorie(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            $aCategory = get_the_category($request["positionId"]);
            if ($aCategory){
                return self::api_success($aCategory[0]->name);
            }
            return self::api_error('Pas de catégorie pour l\'id '.$request['positionId']);
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne le titre d'un article
     * Requête action=title ; positionId=IdArticle
     */
    public static function title(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            return self::api_success(get_post_field('post_title', $request["positionId"]));
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne le contenu d'un article
     * Requête action=contenu ; positionId=IdArticle
     */
    public static function contenu(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            return self::api_success(get_post_field('post_content', $request["positionId"]));
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Retourne l'url de l'image a la une (thumbnail)
     * Requête action=get_image_une ; positionId=IdArticle
     */
    public static function get_image_une(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            return self::api_success(get_the_post_thumbnail_url($request["positionId"]));
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Crée une nouvelle catégorie
     * Retourne l'id de la catégorie crée
     * Requête action=new_category ; category=MaCategorie
     */
    public static function new_category(WP_REST_Request $request){
        if (isset($request['category'])) {
            $idCategory = wp_insert_term($request['category'],'category');
            if(!is_wp_error($image)){
                return self::api_success($idCategory['term_id']);
            }
            return self::api_error($idCategory->get_error_message());
        }
        return self::api_error('Argument category manquant');
    }

    /*
     * Crée un nouvel article
     * Retourne l'id de l'article crée
     * Requête action=newpost ; title=MonTitre ; content=MonContenu ; idcategory=MaCategorie ; date=MaDate ; type=MonTypeDePost ; menu_order=MonRangement ; url=(UrlSansRoot) ; url_image=UrlDeMonImage ; alt_image=MaBaliseAlt
     * Exemple Option URL : les-7-conseils-beautes-du-jour -> https://www.mon_site.com/les-7-conseils-beautes-du-jour
     */
    public static function newpost(WP_REST_Request $request){
        if (isset($request["title"], $request["content"], $request["idcategory"], $request["date"], $request["type"], $request["menu_order"], $request["url"], $request['url_image'], $request['alt_image'])) {
            $article_a = array(
                'post_title' => $request["title"],
                'post_content' => $request["content"],
                'post_status' => 'publish',
                'post_author'   => self::get_first_author_id(),
                'post_category' => array( $request["idCategory"], ),
                'post_type' => $request["type"],
                'menu_order' => $request["menu_order"],
                'post_name' => $request['url']
            );
            if ($request['date'] != 0) {
                $article_a['post_date'] = $request["date"];
            }
            remove_all_filters("content_save_pre"); // Enlever les filtres de securité de wordpress qui enlève des balises du contenus etc.
            $id_article = wp_insert_post($article_a);
            if( !is_wp_error($id_article) && $id_article > 0 ) {
                $statut = self::up_image($request); // Upload Image
                if (isset($statut['success'])){
                    $request['url_image'] = $statut['data'];
                    $request["id_post"] = $id_article;
                    $statut = self::set_image_une($request); // Set Thumbnail
                    if (isset($statut['success'])){
                        return self::api_success($id_article);
                    }
                    return self::api_error('Image upload, echec lors de la mise en place du thumbnail : '.$statut['error']);
                }
                return self::api_error('Erreur lors de l\'upload de l\'image : '.$statut['error']);
            }
            return self::api_error($id_article->get_error_message());
        }
        return self::api_error("Argument manquant (format de la requete : action=newpost ; title=MonTitre ; content=MonContenu ; idCategory=MaCategorie ; date=MaDate ; type=MonTypeDePost ; menu_order=MonRangement ; url=(UrlSansRoot) ; url_image=UrlDeMonImage ; alt_image=MaBaliseAlt)");
    }

    private static function get_first_author_id() {
        $author = get_users( array(
            'role' => 'author',
            'orderby' => 'registered',
            'order' => 'ASC',
            'number' => 1
        ) );
        return $author->ID ?? 1;
    }

    /*
     * Modifie le titre et le contenu d'un article
     * Requête action=update_post_content ; title=MonTitre ; content=MonContenu ; positionId=MonArticle ; url=(UrlSansRoot)
     * Optionnel : url_image=UrlDeMonImage ; alt_image=MaBaliseAlt
     */
    public static function update_post_content(WP_REST_Request $request){
        if (isset($request["title"], $request["content"], $request['positionId'], $request["url"])) {
            $article_a = array(
                'post_title' => $request["title"],
                'post_content' => $request["content"],
                'ID' => $request['positionId'],
                'post_name' => $request['url']
            );
            remove_all_filters("content_save_pre"); //enlever les filtres de securité de wordpress qui enlève des balises du contenus etc.
            $id_article = wp_update_post($article_a);
            if( !is_wp_error($id_article) && $id_article > 0 ) {
                if (isset($request['url_image'], $request['alt_image'])){
                    self::delete_image($request);
                    $statut = self::up_image($request); // Upload Image
                    if (isset($statut['success'])){
                        $request['url_image'] = $statut['data'];
                        $request["id_post"] = $id_article;
                        $statut = self::set_image_une($request); // Set Thumbnail
                        if (isset($statut['success'])){
                            return self::api_success($id_article);
                        }
                        return self::api_error('Image upload, echec lors de la mise en place du thumbnail : '.$statut['error']);
                    }
                    return self::api_error('Erreur lors de l\'upload de l\'image : '.$statut['error']);
                }
                return self::api_success(1);
            }
            return self::api_error($id_article->get_error_message());
        }
        return self::api_error("Argument manquant (format de la requete : action=newpost ; title=MonTitre ; content=MonContenu ; positionId=MonArticle)");
    }

    /*
     * Supprime un article
     * Requête action=delete_post ; positionId=MonArticle
     */
    public static function delete_post(WP_REST_Request $request){
        if (isset($request['positionId'])) {
            $statut = wp_delete_post($request['positionId'], true);
            if(!is_wp_error($statut)){
                return self::api_success(1);
            }
            return self::api_error($image->get_error_message());
        }
        return self::api_error('Argument positionId manquant');
    }

    /*
     * Upload une image
     * Retourne l'url de l'image upload
     * Requête action=up_image ; url_image=UrlDeMonImage ; alt_image=MaBaliseAlt
     */
    public static function up_image(WP_REST_Request $request){
        if (isset($request['url_image'], $request['alt_image'])) {
            $image = media_sideload_image($request["url_image"], '0', $request["alt_image"], "src");
            if(!is_wp_error($image)){
                return self::api_success($image);
            }
            return self::api_error($image->get_error_message());
        }
        return self::api_error("Argument manquant (format de la requete : action=up_image ; url_image=UrlDeMonImage ; alt_image=MaBaliseAlt");
    }

    /*
     * Poste une image d'entête à un article
     * Retourne un id
     * Requête action=set_image_une ; url_image=UrlDeMonImage ; id_post=IdDeMonArticle
     */
    public static function set_image_une(WP_REST_Request $request){
        if (isset($request['url_image'], $request['id_post'])) {
            $id_image = self::pn_get_attachment_id_from_url($request['url_image']);
            set_post_thumbnail($request['id_post'], $id_image);
            if(!is_wp_error($id_image)){
                return self::api_success($id_image);
            }
            return self::api_error($id_image->get_error_message());
        }
        return self::api_error("Argument manquant (format de la requete : action=set_image_une ; url_image=UrlDeMonImage ; id_post=IdDeMonArticle");
    }

    /*
     * Change le format d'un post
     * Requête action=set_post_format ; post_format=MonFormat ; id_post=IdDeMonArticle
     */
    public static function set_post_format(WP_REST_Request $request){
        if (isset($request["id_post"], $request["post_format"])) {
            set_post_format($request["id_post"], $request["post_format"]);
            if(!is_wp_error($image)){
                return self::api_success(1);
            }
            return self::api_error($idCategory->get_error_message());
        }
        return self::api_error('Argument manquant (format de la requete : action=set_post_format ; post_format=MonFormat ; id_post=IdDeMonArticle');
    }

    /*
     * Supprime un media
     * Requête action=delete_image ; positionId=MonArticle
     */
    public static function delete_image(WP_REST_Request $request){
        if (isset($request["positionId"])){
            $tId = get_post_thumbnail_id($request["positionId"]);
            if($tId){
                if (wp_delete_attachment($tId, true)){
                    return self::api_success(1);
                }
                return self::api_error('Something went wrong');
            }
            return self::api_error($request["positionId"].' : Id inconnu');
        }
    }

    /*
     * Retourne le nom d'une catégorie
     * Requête action=get_cat_slug_by_id ; id_category=IdDeMaCategorie
     */
    public static function get_cat_slug_by_id(WP_REST_Request $request){
        if (isset($request['id_category'])) {
            $category = get_category((int)$request["id_category"]);
            if(is_object($category)){
                return self::api_success($category->slug);
            }
            return self::api_error('Catégorie non trouvé : '.$request["id_category"]);
        }
        return self::api_error('Argument id_category manquant');
    }

    /*
     * Retourne le nombre d'articles d'un blog
     * Requête action=count_post
     */
    public static function count_post(WP_REST_Request $request){
        return self::api_success(wp_count_posts()->publish);
    }

    /*
     * Retourne un tableau avec tous les id des articles du blog
     * Requête action=get_all_post
     */
    public static function get_all_post(WP_REST_Request $request){
        return self::api_success(get_posts(array('numberposts' => -1)));
    }

    /*
     * Retourne l'id d'un article selon son url
     * Requête action=get_post_id ; post_url=MonUrl
     */
    public static function get_post_id(WP_REST_Request $request){
        if (isset($request['post_url'])) {
            return self::api_success(url_to_postid($request['post_url']));
        }
        return self::api_error('Argument post_url manquant');
    }

    /*
     * Change les metadonnées d'un article via son url
     * Requête action=change_url_meta_infos ; post_url=MonFormat ; meta_key=IdDeMonArticle ; meta_value=MetaValue
     */
    public static function change_url_meta_infos(WP_REST_Request $request){
        if (isset($request['post_url'], $request['meta_key'], $request['meta_value'])) {
            $post_id = url_to_postid($request["post_url"]);
            if($post_id != 0){
                update_post_meta( $post_id, $request["meta_key"], $request["meta_value"]);
                return self::api_success(1);
            }
            return self::api_error('Url non valide');
        }
        return self::api_error('Argument manquant (format de la requete : action=change_url_meta_infos ; post_url=MonFormat ; meta_key=IdDeMonArticle ; meta_value=MetaValue');
    }

    /*
     * Retourne un tableau de toutes les correspondances id / categories
     * Requête action=get_all_category
     */
    public static function get_all_category(WP_REST_Request $request){
        $aCategory = array();
        $args = array(
            'hide_empty'      => false,
        );
        foreach(get_categories($args) as $wp_objet){
            if($wp_objet->category_parent == 0){
                $aCategory[$wp_objet->cat_ID] = trim($wp_objet->name);
            }
        }
        krsort($aCategory);
        return self::api_success($aCategory);
    }

    /*
     * Déactive le lien entre le plugin et LG
     * Requête action=remove_ownership
     */
    public static function remove_ownership(WP_REST_Request $request){
        LinksgardenConfig::delete_lg_options(false);
        return self::api_success('Unlinked');
    }

    public static function api_success($data, $code = 1){
        return array('code' => $code, 'data' => $data, 'success' => 1);
    }

    public static function api_error($data, $code = -1){
        return array('code' => $code, 'data' => $data);
    }

    private static function pn_get_attachment_id_from_url( $attachment_url = '' ) {
       global $wpdb;
       $attachment_id = false;
        // If there is no url, return.
        if ( '' == $attachment_url )
           return;
        // Get the upload directory paths
        $upload_dir_paths = wp_upload_dir();
        // Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
        if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
            // If this is the URL of an auto-generated thumbnail, get the URL of the original image
            $attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
            // Remove the upload path base directory from the attachment URL
            $attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
            // Finally, run a custom database query to get the attachment ID from the modified attachment URL
            $attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
        }
        return $attachment_id;
    }
}
