<?php
/**
 * WP Social Buffer API Handler
 *
 * @package MKM_DSPB_Bridge
 * @version 2.0.2
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

if ( ! class_exists( 'MKM_DSPB_API' ) ) {
    class MKM_DSPB_API {

    private $api_url = 'https://api.buffer.com';

    /**
     * Executes a GraphQL query against Buffer API
     */
    private function query( $token, $query, $variables = array() ) {
        $headers = array(
            'Authorization' => 'Bearer ' . $token,
            'Content-Type'  => 'application/json',
            'User-Agent'    => 'WordPress MKM Digital Social Publisher Bridge to Buffer',
        );

        $body = array(
            'query' => $query,
        );

        if ( ! empty( $variables ) ) {
            $body['variables'] = $variables;
        }

        $args = array(
            'headers'   => $headers,
            'body'      => wp_json_encode( $body ),
            'timeout'   => 30,
            'sslverify' => true,
        );

        $response = wp_remote_post( $this->api_url, $args );

        if ( is_wp_error( $response ) ) {
            return $response;
        }

        $res_body = wp_remote_retrieve_body( $response );
        $data     = json_decode( $res_body, true );

        if ( isset( $data['errors'] ) ) {
            return new WP_Error( 'buffer_api_error', $data['errors'][0]['message'], $data['errors'] );
        }

        return isset( $data['data'] ) ? $data['data'] : array();
    }

    /**
     * Fetch all organizations and social channels connected to Buffer
     */
    public function fetch_channels( $token ) {
        if ( empty( $token ) ) {
            return new WP_Error( 'missing_token', __( 'Access Token is missing.', 'mkmdigital-social-publisher-bridge' ) );
        }

        // 1. Get organizations
        $org_query = '
        query GetOrganizations {
          account {
            id
            organizations {
              id
              name
            }
          }
        }';

        $org_data = $this->query( $token, $org_query );
        if ( is_wp_error( $org_data ) ) {
            return $org_data;
        }

        if ( empty( $org_data['account']['organizations'] ) ) {
            return new WP_Error( 'no_orgs', __( 'No organizations found in this Buffer account.', 'mkmdigital-social-publisher-bridge' ) );
        }

        $organizations = $org_data['account']['organizations'];
        $profiles_map  = array();

        // 2. Fetch channels for each organization
        $channels_query = '
        query GetChannels($orgId: OrganizationId!) {
          channels(input: { organizationId: $orgId }) {
            id
            service
            name
            avatar
          }
        }';

        foreach ( $organizations as $org ) {
            $org_id   = $org['id'];
            $chan_data = $this->query( $token, $channels_query, array( 'orgId' => $org_id ) );

            if ( is_wp_error( $chan_data ) ) {
                continue; // Skip failed org
            }

            if ( ! empty( $chan_data['channels'] ) ) {
                foreach ( $chan_data['channels'] as $channel ) {
                    $c_id      = $channel['id'];
                    $c_service = $channel['service'];
                    $c_name    = $channel['name'];
                    $c_avatar  = isset( $channel['avatar'] ) ? $channel['avatar'] : '';

                    // Sanitized key for WordPress option key/form name
                    $key = sprintf( '%s_%s', $c_service, sanitize_key( $c_name ) );
                    
                    $profiles_map[ $key ] = array(
                        'id'      => $c_id,
                        'service' => $c_service,
                        'name'    => $c_name,
                        'avatar'  => $c_avatar,
                    );
                }
            }
        }

        return $profiles_map;
    }

    /**
     * Publishes a post to a specific Buffer channel
     */
    public function publish_post( $token, $text, $channel_id, $service, $media_url = '', $share_now = false ) {
        if ( empty( $token ) ) {
            return new WP_Error( 'missing_token', __( 'Access Token is missing.', 'mkmdigital-social-publisher-bridge' ) );
        }

        $mutation = '
        mutation CreatePost($input: CreatePostInput!) {
          createPost(input: $input) {
            ... on PostActionSuccess {
              post {
                id
                text
              }
            }
            ... on MutationError {
              message
            }
          }
        }';

        // Correct scheduling values for immediate vs queued publishing
        $scheduling_type = 'automatic';
        $mode            = $share_now ? 'shareNow' : 'addToQueue';

        $input = array(
            'text'           => $text,
            'channelId'      => $channel_id,
            'schedulingType' => $scheduling_type,
            'mode'           => $mode,
        );

        // Add platform specific metadata
        if ( 'facebook' === $service ) {
            $input['metadata'] = array( 'facebook' => array( 'type' => 'post' ) );
        } elseif ( 'instagram' === $service ) {
            $input['metadata'] = array( 'instagram' => array( 'type' => 'post', 'shouldShareToFeed' => true ) );
        } elseif ( 'googlebusiness' === $service ) {
            $input['metadata'] = array(
                'google' => array(
                    'type'             => 'whats_new',
                    'detailsWhatsNew' => array(
                        'button' => 'none',
                    ),
                ),
            );
        }

        // Add media asset(s) if present
        $assets = array();
        if ( ! empty( $media_url ) ) {
            $url_list = is_array( $media_url ) ? $media_url : array( $media_url );
            foreach ( $url_list as $single_url ) {
                if ( ! empty( $single_url ) && is_string( $single_url ) ) {
                    $encoded_url = class_exists( 'MKM_DSPB_Publisher' ) && method_exists( 'MKM_DSPB_Publisher', 'encode_media_url' )
                        ? MKM_DSPB_Publisher::encode_media_url( $single_url )
                        : $single_url;
                    $assets[] = array(
                        'image' => array(
                            'url' => $encoded_url,
                        ),
                    );
                }
            }
        }

        // Instagram fallback guardrail: Instagram strictly requires at least one image or video
        if ( 'instagram' === $service && empty( $assets ) ) {
            $fallback_url = '';
            if ( class_exists( 'MKM_DSPB_Publisher' ) && method_exists( 'MKM_DSPB_Publisher', 'get_fallback_media_url' ) ) {
                $fallback_url = MKM_DSPB_Publisher::get_fallback_media_url();
            } elseif ( function_exists( 'get_site_icon_url' ) && get_site_icon_url( 512 ) ) {
                $fallback_url = get_site_icon_url( 512 );
            }

            if ( ! empty( $fallback_url ) ) {
                $encoded_url = class_exists( 'MKM_DSPB_Publisher' ) && method_exists( 'MKM_DSPB_Publisher', 'encode_media_url' )
                    ? MKM_DSPB_Publisher::encode_media_url( $fallback_url )
                    : $fallback_url;
                $assets[] = array(
                    'image' => array(
                        'url' => $encoded_url,
                    ),
                );
            }
        }

        if ( ! empty( $assets ) ) {
            $input['assets'] = $assets;
        }

        $res = $this->query( $token, $mutation, array( 'input' => $input ) );

        if ( is_wp_error( $res ) ) {
            return $res;
        }

        if ( isset( $res['createPost']['message'] ) ) {
            return new WP_Error( 'buffer_mutation_error', $res['createPost']['message'] );
        }

        if ( isset( $res['createPost']['post']['id'] ) ) {
            return $res['createPost']['post']['id'];
        }

        return new WP_Error( 'unknown_error', __( 'Failed to publish to Buffer.', 'mkmdigital-social-publisher-bridge' ) );
    }
    }
}
