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

class VMO_Promotion_TikTok_Connector extends VMO_Promotion_OAuth2_Connector {
    protected function build_authorization_url(array $settings, array $scopes, $state) {
        return add_query_arg(array(
            'client_key' => $this->get_client_identifier($settings),
            'response_type' => 'code',
            'scope' => implode(',', $scopes),
            'redirect_uri' => $this->get_callback_url(),
            'state' => $state,
            'disable_auto_auth' => '0',
        ), 'https://www.tiktok.com/v2/auth/authorize/');
    }

    protected function get_token_endpoint() {
        return 'https://open.tiktokapis.com/v2/oauth/token/';
    }

    protected function build_token_request_body($code, array $state_payload, array $settings) {
        return array(
            'client_key' => $this->get_client_identifier($settings),
            'client_secret' => $this->get_client_secret($settings),
            'code' => (string) $code,
            'grant_type' => 'authorization_code',
            'redirect_uri' => $this->get_callback_url(),
        );
    }

    protected function build_refresh_request_body($refresh_token, array $settings) {
        return array(
            'client_key' => $this->get_client_identifier($settings),
            'client_secret' => $this->get_client_secret($settings),
            'grant_type' => 'refresh_token',
            'refresh_token' => (string) $refresh_token,
        );
    }

    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();
        }

        $creator_info = $this->tiktok_post('/v2/post/publish/creator_info/query/', $access_token, array());
        if (is_wp_error($creator_info)) {
            return $creator_info;
        }

        $creator = (array) ($creator_info['data'] ?? array());
        $raw = (array) ($token_context['raw_response'] ?? array());
        $open_id = sanitize_text_field($raw['open_id'] ?? '');

        return array(
            array(
                'platform_key' => 'tiktok',
                'platform_label' => 'TikTok',
                'external_account_id' => $open_id !== '' ? $open_id : 'tiktok_creator',
                'display_name' => sanitize_text_field($creator['creator_nickname'] ?? $creator['creator_username'] ?? 'TikTok Creator'),
                'auth_status' => 'connected',
                'connection_metadata' => array(
                    'connection_role' => 'tiktok_creator',
                    'open_id' => $open_id,
                    'creator_username' => sanitize_text_field($creator['creator_username'] ?? ''),
                    'creator_avatar_url' => esc_url_raw($creator['creator_avatar_url'] ?? ''),
                    'privacy_level_options' => array_values((array) ($creator['privacy_level_options'] ?? array())),
                    'comment_disabled' => !empty($creator['comment_disabled']),
                    'duet_disabled' => !empty($creator['duet_disabled']),
                    'stitch_disabled' => !empty($creator['stitch_disabled']),
                    'max_video_post_duration_sec' => (int) ($creator['max_video_post_duration_sec'] ?? 0),
                ),
            ),
        );
    }

    public function publish_text_post(array $input) {
        return new WP_Error('provider_not_ready', 'TikTok publishing requires photo or video media. Use the media publishing flow for this provider.');
    }

    public function publish_media_post(array $input) {
        $account = $this->get_account($input);
        if (empty($account['access_token'])) {
            return new WP_Error('missing_connected_account', 'A connected TikTok creator account is required before publishing.');
        }

        $content_item = (array) ($input['content_item'] ?? array());
        $asset = $this->extract_asset($content_item);
        if (empty($asset['url'])) {
            return new WP_Error('missing_media_asset', 'TikTok publishing requires a publicly reachable image or video URL.');
        }

        $creator_info = $this->tiktok_post('/v2/post/publish/creator_info/query/', $account['access_token'], array());
        if (is_wp_error($creator_info)) {
            return $creator_info;
        }

        $creator = (array) ($creator_info['data'] ?? array());
        $privacy_options = array_values((array) ($creator['privacy_level_options'] ?? array('SELF_ONLY')));
        $privacy_level = sanitize_text_field($privacy_options[0] ?? 'SELF_ONLY');
        $title = $this->truncate_text(sanitize_text_field($content_item['title'] ?? ''), 90);
        $description = $this->truncate_text($this->get_caption($content_item), 2200);
        $mime = strtolower((string) ($asset['type'] ?? ''));

        if (strpos($mime, 'video/') === 0) {
            $payload = array(
                'post_info' => array(
                    'title' => $title !== '' ? $title : $description,
                    'privacy_level' => $privacy_level,
                    'disable_duet' => !empty($creator['duet_disabled']),
                    'disable_comment' => !empty($creator['comment_disabled']),
                    'disable_stitch' => !empty($creator['stitch_disabled']),
                ),
                'source_info' => array(
                    'source' => 'PULL_FROM_URL',
                    'video_url' => esc_url_raw($asset['url']),
                ),
            );

            $response = $this->tiktok_post('/v2/post/publish/video/init/', $account['access_token'], $payload);
            if (is_wp_error($response)) {
                return $response;
            }

            return array(
                'provider_post_id' => sanitize_text_field($response['data']['publish_id'] ?? ''),
                'message' => 'TikTok accepted the video publish job.',
                'response' => $response,
            );
        }

        $payload = array(
            'post_info' => array(
                'title' => $title,
                'description' => $description,
                'disable_comment' => !empty($creator['comment_disabled']),
                'privacy_level' => $privacy_level,
                'auto_add_music' => true,
            ),
            'source_info' => array(
                'source' => 'PULL_FROM_URL',
                'photo_cover_index' => 1,
                'photo_images' => array(esc_url_raw($asset['url'])),
            ),
            'post_mode' => 'DIRECT_POST',
            'media_type' => 'PHOTO',
        );

        $response = $this->tiktok_post('/v2/post/publish/content/init/', $account['access_token'], $payload);
        if (is_wp_error($response)) {
            return $response;
        }

        return array(
            'provider_post_id' => sanitize_text_field($response['data']['publish_id'] ?? ''),
            'message' => 'TikTok accepted the photo publish job.',
            'response' => $response,
        );
    }

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

    public function list_replies(array $input) {
        return new WP_Error('provider_not_ready', 'TikTok reply ingestion is not activated yet in this build.');
    }

    public function reply_to_comment(array $input) {
        return new WP_Error('provider_not_ready', 'TikTok reply publishing is not activated yet in this build.');
    }

    protected function tiktok_post($path, $access_token, array $body) {
        $response = wp_remote_post('https://open.tiktokapis.com' . $path, array(
            'timeout' => 30,
            'headers' => array(
                'Authorization' => 'Bearer ' . $access_token,
                'Accept' => 'application/json',
                'Content-Type' => 'application/json; charset=UTF-8',
            ),
            'body' => wp_json_encode($body),
        ));

        $parsed = $this->parse_remote_response($response);
        if (is_wp_error($parsed)) {
            return $parsed;
        }

        if (!empty($parsed['error']['code']) && $parsed['error']['code'] !== 'ok') {
            return new WP_Error(
                sanitize_key($parsed['error']['code']),
                sanitize_text_field($parsed['error']['message'] ?? 'TikTok API request failed.'),
                array(
                    'platform_key' => 'tiktok',
                    'response' => $parsed,
                )
            );
        }

        return $parsed;
    }

    protected function get_account(array $input) {
        if (!$this->store || !method_exists($this->store, 'get_connected_account_auth_rows')) {
            return (array) ($input['connected_account'] ?? array());
        }

        $user_id = (int) ($input['user_id'] ?? 0);
        if ($user_id <= 0) {
            return (array) ($input['connected_account'] ?? array());
        }

        $target = (array) ($input['connected_account'] ?? array());
        $rows = $this->store->get_connected_account_auth_rows($user_id, 'tiktok');
        if (empty($rows)) {
            return $target;
        }

        if (!empty($target['id'])) {
            foreach ($rows as $row) {
                if ((int) $row['id'] === (int) $target['id']) {
                    return $row;
                }
            }
        }

        return $rows[0];
    }

    protected function get_caption(array $content_item) {
        $caption = sanitize_textarea_field($content_item['caption_master'] ?? '');
        $cta = esc_url_raw($content_item['cta_url'] ?? '');
        if ($cta !== '' && strpos($caption, $cta) === false) {
            $caption = trim($caption . "\n\n" . $cta);
        }

        return trim($caption);
    }

    protected function extract_asset(array $content_item) {
        $bundle = (array) ($content_item['media_bundle'] ?? array());
        $assets = array_values((array) ($bundle['manual_assets'] ?? array()));
        if (empty($assets)) {
            return array();
        }

        return (array) $assets[0];
    }

    protected function truncate_text($value, $limit) {
        $value = trim((string) $value);
        if ($value === '') {
            return '';
        }

        if (function_exists('mb_strlen') && function_exists('mb_substr')) {
            return mb_strlen($value) > $limit ? rtrim(mb_substr($value, 0, $limit - 1)) : $value;
        }

        return strlen($value) > $limit ? rtrim(substr($value, 0, $limit - 1)) : $value;
    }
}
