<?php
if (!defined('ABSPATH')) {
    exit;
}

class VMO_Promotion_Meta_Connector extends VMO_Promotion_OAuth2_Connector {
    const GRAPH_VERSION = 'v22.0';

    protected function build_authorization_url(array $settings, array $scopes, $state) {
        return add_query_arg(array(
            'client_id' => $this->get_client_identifier($settings),
            'redirect_uri' => $this->get_callback_url(),
            'state' => $state,
            'scope' => implode(',', $scopes),
            'response_type' => 'code',
        ), 'https://www.facebook.com/' . self::GRAPH_VERSION . '/dialog/oauth');
    }

    protected function get_token_endpoint() {
        return 'https://graph.facebook.com/' . self::GRAPH_VERSION . '/oauth/access_token';
    }

    protected function exchange_authorization_code($code, array $state_payload) {
        $token_context = parent::exchange_authorization_code($code, $state_payload);
        if (is_wp_error($token_context) || empty($token_context['access_token'])) {
            return $token_context;
        }

        $settings = $this->get_settings();
        $extended = $this->parse_remote_response(wp_remote_get(add_query_arg(array(
            'grant_type' => 'fb_exchange_token',
            'client_id' => $this->get_client_identifier($settings),
            'client_secret' => $this->get_client_secret($settings),
            'fb_exchange_token' => $token_context['access_token'],
        ), $this->get_token_endpoint()), array(
            'timeout' => 20,
            'headers' => array('Accept' => 'application/json'),
        )), true);

        if (is_wp_error($extended) || empty($extended['access_token'])) {
            return $token_context;
        }

        if (empty($extended['refresh_token'])) {
            $extended['refresh_token'] = '';
        }

        return array_merge($token_context, $extended);
    }

    protected function discover_remote_accounts($user_id, array $token_context, array $request_context = array()) {
        $access_token = (string) ($token_context['access_token'] ?? '');
        if ($access_token === '') {
            return array();
        }

        $user = $this->meta_get('/me', $access_token, array(
            'fields' => 'id,name',
        ));
        if (is_wp_error($user)) {
            return $user;
        }

        $user_id_remote = sanitize_text_field($user['id'] ?? '');
        $user_name = sanitize_text_field($user['name'] ?? $this->platform_label . ' User');
        $accounts = array(
            array(
                'platform_key' => $this->platform_key,
                'platform_label' => $this->platform_label,
                'external_account_id' => 'meta_user_' . $user_id_remote,
                'display_name' => $user_name,
                'auth_status' => 'connected',
                'connection_metadata' => array(
                    'connection_role' => 'oauth_user',
                    'meta_user_id' => $user_id_remote,
                    'provider_family' => 'meta',
                ),
                'publish_enabled' => false,
                'reply_enabled' => false,
                'metrics_enabled' => false,
            ),
        );

        $pages = $this->meta_get('/me/accounts', $access_token, array(
            'fields' => 'id,name,access_token,tasks,instagram_business_account{id,username},connected_instagram_account{id,username}',
            'limit' => 100,
        ));

        if (is_wp_error($pages)) {
            return $accounts;
        }

        foreach ((array) ($pages['data'] ?? array()) as $page) {
            $page_id = sanitize_text_field($page['id'] ?? '');
            $page_name = sanitize_text_field($page['name'] ?? '');
            $page_token = sanitize_text_field($page['access_token'] ?? $access_token);

            if ($this->platform_key === 'facebook' && $page_id !== '') {
                $accounts[] = array(
                    'platform_key' => 'facebook',
                    'platform_label' => 'Facebook',
                    'external_account_id' => $page_id,
                    'display_name' => $page_name ?: ('Facebook Page ' . $page_id),
                    'auth_status' => 'connected',
                    'access_token' => $page_token,
                    'refresh_token' => '',
                    'token_expires_at' => sanitize_text_field($token_context['token_expires_at'] ?? ''),
                    'connection_metadata' => array(
                        'connection_role' => 'page',
                        'page_id' => $page_id,
                        'page_name' => $page_name,
                        'tasks' => array_values((array) ($page['tasks'] ?? array())),
                        'meta_user_id' => $user_id_remote,
                    ),
                );
            }

            if ($this->platform_key === 'instagram') {
                $ig_account = array();
                if (!empty($page['instagram_business_account'])) {
                    $ig_account = (array) $page['instagram_business_account'];
                } elseif (!empty($page['connected_instagram_account'])) {
                    $ig_account = (array) $page['connected_instagram_account'];
                }

                $ig_id = sanitize_text_field($ig_account['id'] ?? '');
                if ($ig_id !== '') {
                    $accounts[] = array(
                        'platform_key' => 'instagram',
                        'platform_label' => 'Instagram',
                        'external_account_id' => $ig_id,
                        'display_name' => sanitize_text_field($ig_account['username'] ?? $page_name ?: ('Instagram Account ' . $ig_id)),
                        'auth_status' => 'connected',
                        'access_token' => $page_token,
                        'refresh_token' => '',
                        'token_expires_at' => sanitize_text_field($token_context['token_expires_at'] ?? ''),
                        'connection_metadata' => array(
                            'connection_role' => 'instagram_business',
                            'instagram_user_id' => $ig_id,
                            'page_id' => $page_id,
                            'page_name' => $page_name,
                            'meta_user_id' => $user_id_remote,
                        ),
                    );
                }
            }
        }

        if ($this->platform_key === 'threads') {
            $accounts[0]['connection_metadata']['threads_ready'] = false;
            $accounts[0]['connection_metadata']['threads_note'] = 'Threads connection is authorized through the Meta family, but publishing remains provider-specific.';
        }

        return $accounts;
    }

    public function publish_text_post(array $input) {
        if ($this->platform_key === 'facebook') {
            $account = $this->get_platform_account_record($input);
            if (empty($account['access_token']) || empty($account['external_account_id'])) {
                return new WP_Error('missing_connected_account', 'A connected Facebook page is required before publishing.');
            }

            $content_item = (array) ($input['content_item'] ?? array());
            $payload = array(
                'message' => $this->get_post_caption($content_item),
            );
            $cta_url = esc_url_raw($content_item['cta_url'] ?? '');
            if ($cta_url !== '') {
                $payload['link'] = $cta_url;
            }

            $response = $this->meta_post('/' . rawurlencode($account['external_account_id']) . '/feed', $account['access_token'], $payload);
            if (is_wp_error($response)) {
                return $response;
            }

            return array(
                'provider_post_id' => sanitize_text_field($response['id'] ?? ''),
                'message' => 'Published to Facebook.',
                'response' => $response,
            );
        }

        if ($this->platform_key === 'threads') {
            return new WP_Error('provider_not_ready', 'Threads publishing is not activated yet in this build. The connector now handles Meta-family authorization and account state.');
        }

        return new WP_Error('provider_not_ready', 'Instagram text-only publishing is not supported. Attach media and use the media publishing flow instead.');
    }

    public function publish_media_post(array $input) {
        if ($this->platform_key === 'facebook') {
            $account = $this->get_platform_account_record($input);
            if (empty($account['access_token']) || empty($account['external_account_id'])) {
                return new WP_Error('missing_connected_account', 'A connected Facebook page is required before publishing.');
            }

            $content_item = (array) ($input['content_item'] ?? array());
            $asset = $this->extract_primary_asset($content_item);
            if (empty($asset['url'])) {
                return $this->publish_text_post($input);
            }

            $mime = strtolower((string) ($asset['type'] ?? ''));
            if (strpos($mime, 'video/') === 0) {
                $response = $this->meta_post('/' . rawurlencode($account['external_account_id']) . '/videos', $account['access_token'], array(
                    'file_url' => $asset['url'],
                    'description' => $this->get_post_caption($content_item),
                ));
            } else {
                $response = $this->meta_post('/' . rawurlencode($account['external_account_id']) . '/photos', $account['access_token'], array(
                    'url' => $asset['url'],
                    'caption' => $this->get_post_caption($content_item),
                ));
            }

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

            return array(
                'provider_post_id' => sanitize_text_field($response['id'] ?? ''),
                'message' => 'Published media post to Facebook.',
                'response' => $response,
            );
        }

        if ($this->platform_key === 'instagram') {
            $account = $this->get_platform_account_record($input);
            $asset = $this->extract_primary_asset((array) ($input['content_item'] ?? array()));

            if (empty($account['access_token']) || empty($account['external_account_id'])) {
                return new WP_Error('missing_connected_account', 'A connected Instagram business account is required before publishing.');
            }

            if (empty($asset['url'])) {
                return new WP_Error('missing_media_asset', 'Instagram publishing requires a publicly reachable image or video URL.');
            }

            $mime = strtolower((string) ($asset['type'] ?? ''));
            $creation_body = array(
                'caption' => $this->get_post_caption((array) ($input['content_item'] ?? array())),
            );

            if (strpos($mime, 'video/') === 0) {
                $creation_body['media_type'] = 'REELS';
                $creation_body['video_url'] = $asset['url'];
            } else {
                $creation_body['image_url'] = $asset['url'];
            }

            $container = $this->meta_post('/' . rawurlencode($account['external_account_id']) . '/media', $account['access_token'], $creation_body);
            if (is_wp_error($container)) {
                return $container;
            }

            $creation_id = sanitize_text_field($container['id'] ?? '');
            if ($creation_id === '') {
                return new WP_Error('provider_api_error', 'Instagram media container did not return a creation ID.', $container);
            }

            $published = $this->meta_post('/' . rawurlencode($account['external_account_id']) . '/media_publish', $account['access_token'], array(
                'creation_id' => $creation_id,
            ));
            if (is_wp_error($published)) {
                return $published;
            }

            return array(
                'provider_post_id' => sanitize_text_field($published['id'] ?? $creation_id),
                'message' => 'Published media post to Instagram.',
                'response' => $published,
            );
        }

        return new WP_Error('provider_not_ready', 'Threads media publishing is not activated yet in this build.');
    }

    public function list_replies(array $input) {
        $account = $this->get_platform_account_record($input);
        $job = (array) ($input['job'] ?? array());
        $provider_post_id = sanitize_text_field($input['provider_post_id'] ?? ($job['provider_post_id'] ?? ''));

        if ($provider_post_id === '' || empty($account['access_token'])) {
            return new WP_Error('missing_provider_post', 'A provider post ID is required before loading replies.');
        }

        $response = $this->meta_get('/' . rawurlencode($provider_post_id) . '/comments', $account['access_token'], array(
            'fields' => 'id,message,text,username,from{id,name},timestamp',
            'limit' => 100,
        ));

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

        return array(
            'platform_key' => $this->platform_key,
            'replies' => array_values((array) ($response['data'] ?? array())),
        );
    }

    public function reply_to_comment(array $input) {
        $account = $this->get_platform_account_record($input);
        $comment_id = sanitize_text_field($input['comment_id'] ?? '');
        $message = sanitize_textarea_field($input['message'] ?? '');

        if ($comment_id === '' || $message === '' || empty($account['access_token'])) {
            return new WP_Error('missing_reply_context', 'Comment ID, reply message, and connected account are required before sending a reply.');
        }

        $response = $this->meta_post('/' . rawurlencode($comment_id) . '/comments', $account['access_token'], array(
            'message' => $message,
        ));

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

        return array(
            'platform_key' => $this->platform_key,
            'provider_reply_id' => sanitize_text_field($response['id'] ?? ''),
            'message' => 'Reply sent.',
            'response' => $response,
        );
    }

    public function fetch_metrics(array $input) {
        return new WP_Error('provider_not_ready', 'Cross-platform Meta metrics normalization is not finalized yet in this build.');
    }

    public function list_ad_accounts(array $input) {
        $account = $this->get_platform_account_record($input);
        if (empty($account['access_token'])) {
            return new WP_Error('missing_connected_account', 'A connected Meta account is required before loading ad accounts.');
        }

        $response = $this->meta_get('/me/adaccounts', $account['access_token'], array(
            'fields' => 'id,account_id,name,account_status,currency,business{name}',
            'limit' => 100,
        ));
        if (is_wp_error($response)) {
            return $response;
        }

        $accounts = array();
        foreach ((array) ($response['data'] ?? array()) as $item) {
            $accounts[] = array(
                'id' => sanitize_text_field($item['id'] ?? ''),
                'account_id' => sanitize_text_field($item['account_id'] ?? ''),
                'name' => sanitize_text_field($item['name'] ?? ''),
                'currency' => sanitize_text_field($item['currency'] ?? ''),
                'account_status' => sanitize_text_field($item['account_status'] ?? ''),
                'business_name' => sanitize_text_field($item['business']['name'] ?? ''),
            );
        }

        return array(
            'platform_key' => $this->platform_key,
            'ad_management_supported' => true,
            'accounts' => $accounts,
        );
    }

    public function create_ad_draft(array $input) {
        $account = $this->get_platform_account_record($input);
        if (empty($account['access_token'])) {
            return new WP_Error('missing_connected_account', 'A connected Meta account is required before creating an ad draft.');
        }

        $settings = $this->get_settings();
        $draft = (array) ($input['draft'] ?? array());
        $ad_account_id = sanitize_text_field($draft['ad_account_id'] ?? ($settings['ad_account_id'] ?? ''));
        if ($ad_account_id === '') {
            return new WP_Error('missing_ad_account_id', 'A Meta ad account ID is required before creating an ad draft.');
        }

        $creative = (array) ($draft['creative_payload'] ?? array());
        $objective = sanitize_text_field($draft['objective'] ?? 'OUTCOME_TRAFFIC');
        $name = sanitize_text_field($draft['name'] ?? (($creative['headline'] ?? '') ?: ('VMO Campaign ' . gmdate('Y-m-d H:i'))));
        if ($name === '') {
            $name = 'VMO Campaign ' . gmdate('Y-m-d H:i');
        }

        $response = $this->meta_post('/act_' . rawurlencode($ad_account_id) . '/campaigns', $account['access_token'], array(
            'name' => $name,
            'objective' => $objective,
            'status' => 'PAUSED',
            'special_ad_categories' => '[]',
        ));
        if (is_wp_error($response)) {
            return $response;
        }

        return array(
            'platform_key' => $this->platform_key,
            'draft_created' => true,
            'provider_campaign_id' => sanitize_text_field($response['id'] ?? ''),
            'ad_account_id' => $ad_account_id,
            'message' => 'Meta campaign draft created in paused state.',
            'response' => $response,
        );
    }

    public function launch_ad_campaign(array $input) {
        return new WP_Error(
            'provider_not_ready',
            'Meta ad launch is not activated yet in this build. Campaign drafts can be created, but ad set, targeting, creative, and placement assembly are still pending.'
        );
    }

    public function fetch_ad_metrics(array $input) {
        return new WP_Error('provider_not_ready', 'Meta ad metrics normalization is not finalized yet in this build.');
    }

    protected function meta_get($path, $access_token, array $query = array()) {
        $query['access_token'] = $access_token;
        $url = add_query_arg($query, 'https://graph.facebook.com/' . self::GRAPH_VERSION . $path);
        return $this->parse_remote_response(wp_remote_get($url, array(
            'timeout' => 20,
            'headers' => array('Accept' => 'application/json'),
        )));
    }

    protected function meta_post($path, $access_token, array $body = array()) {
        $body['access_token'] = $access_token;
        return $this->parse_remote_response(wp_remote_post('https://graph.facebook.com/' . self::GRAPH_VERSION . $path, array(
            'timeout' => 30,
            'headers' => array(
                'Accept' => 'application/json',
            ),
            'body' => $body,
        )));
    }
}
