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

class Calliope_SP_Tumblr {

    public function test_connection() {
        $ck = get_option('calliope_sp_tumblr_consumer_key');
        $cs = get_option('calliope_sp_tumblr_consumer_secret');
        $tk = get_option('calliope_sp_tumblr_token');
        $ts = get_option('calliope_sp_tumblr_token_secret');
        $blog = get_option('calliope_sp_tumblr_blog_identifier');

        if (!$ck || !$cs || !$tk || !$ts || !$blog) {
            return new WP_Error('cfg', 'Missing Tumblr configuration (keys/tokens/blog). Use “Connect with Tumblr”.');
        }

        // 1) Validate blog (with api_key)
        $blog_url = 'https://api.tumblr.com/v2/blog/' . rawurlencode($blog) . '/info?api_key=' . rawurlencode($ck);
        $res = wp_remote_get($blog_url, ['timeout' => 30]);
        if (is_wp_error($res)) return $res;

        $code = wp_remote_retrieve_response_code($res);
        $body = json_decode(wp_remote_retrieve_body($res), true);

        if ($code < 200 || $code >= 300) {
            return new WP_Error('tumblr', 'Error (' . $code . '): could not validate the blog.');
        }

        if (is_array($body) && isset($body['meta']['status']) && (int)$body['meta']['status'] !== 200) {
            return new WP_Error('tumblr', 'Error: Tumblr rejected blog validation.');
        }

        // 2) Validate tokens (user/info)
        $user_url = 'https://api.tumblr.com/v2/user/info';
        $auth = $this->build_oauth_header('GET', $user_url, [], $ck, $cs, $tk, $ts);
        $res2 = wp_remote_get($user_url, [
            'timeout' => 30,
            'headers' => [
                'Authorization' => $auth,
            ],
        ]);

        if (is_wp_error($res2)) return $res2;

        $code2 = wp_remote_retrieve_response_code($res2);
        $body2 = json_decode(wp_remote_retrieve_body($res2), true);

        if ($code2 < 200 || $code2 >= 300) {
            $msg = 'could not validate the user.';
            if (is_array($body2) && isset($body2['meta']['msg'])) $msg = $body2['meta']['msg'];
            return new WP_Error('tumblr', 'Error (' . $code2 . '): ' . $msg);
        }

        if (is_array($body2) && isset($body2['meta']['status']) && (int)$body2['meta']['status'] !== 200) {
            $msg = isset($body2['meta']['msg']) ? $body2['meta']['msg'] : 'Invalid tokens.';
            return new WP_Error('tumblr', 'Error: ' . $msg);
        }

        return true;
    }
public function publish($data) {
        $ck = get_option('calliope_sp_tumblr_consumer_key');
        $cs = get_option('calliope_sp_tumblr_consumer_secret');
        $tk = get_option('calliope_sp_tumblr_token');
        $ts = get_option('calliope_sp_tumblr_token_secret');
        $blog = get_option('calliope_sp_tumblr_blog_identifier');

        if (!$ck || !$cs || !$tk || !$ts || !$blog) {
            return new WP_Error('cfg', 'Missing Tumblr configuration (keys/tokens/blog).');
        }

        $caption = '';
        if (!empty($data['title'])) {
            $caption .= '<h1>' . esc_html($data['title']) . '</h1>';
        }
        $caption .= '<p>' . esc_html($data['content'] ?? '') . '</p>';
        if (!empty($data['link'])) {
            $caption .= '<p><a href="' . esc_url($data['link']) . '">👉 Full Article</a></p>';
        }

        $tags_clean = '';
        if (!empty($data['hashtags'])) {
            $temp = str_replace('#', '', (string)$data['hashtags']);
            $temp = preg_replace('/\s+/', ' ', $temp);
            $tags_clean = str_replace(' ', ',', trim($temp));
        }

        $url = 'https://api.tumblr.com/v2/blog/' . rawurlencode($blog) . '/post';

        $post_params = [
            'type' => 'photo',
            'caption' => $caption,
            'tags' => $tags_clean,
            'state' => 'published',
        ];

        if (!empty($data['image_b64'])) {
            $parts = explode('base64,', (string)$data['image_b64'], 2);
            $post_params['data64'] = $parts[1] ?? $parts[0];
        } else {
            // Text-only post
            $post_params['type'] = 'text';
            $post_params['body'] = $caption;
            unset($post_params['caption']);
        }

        $auth_header = $this->generate_oauth_header('POST', $url, $post_params, $ck, $cs, $tk, $ts);

        $res = wp_remote_post($url, [
            'headers' => [
                'Authorization' => $auth_header,
                'Content-Type' => 'application/x-www-form-urlencoded',
            ],
            'body' => http_build_query($post_params),
            'timeout' => 60,
        ]);

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

        $code = wp_remote_retrieve_response_code($res);
        if ($code < 200 || $code >= 300) {
            return new WP_Error('tumblr', 'Error (' . $code . '): could not publish.');
        }

        return true;
    }

    public function oauth_request_token($ck, $cs, $callback_url) {
        $url = 'https://www.tumblr.com/oauth/request_token';

        $oauth_extra = [
            'oauth_callback' => $callback_url,
        ];

        $auth = $this->build_oauth_header('POST', $url, [], $ck, $cs, '', '', $oauth_extra);

        $res = wp_remote_post($url, [
            'timeout' => 30,
            'headers' => [
                'Authorization' => $auth,
            ],
        ]);

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

        $code = wp_remote_retrieve_response_code($res);
        $body = (string) wp_remote_retrieve_body($res);

        if ($code < 200 || $code >= 300) {
            return new WP_Error('tumblr_oauth', 'Error (' . $code . '): could not obtain request token.');
        }

        parse_str($body, $out);
        if (empty($out['oauth_token']) || empty($out['oauth_token_secret'])) {
            return new WP_Error('tumblr_oauth', 'Invalid response while requesting request token.');
        }

        return $out;
    }

    public function oauth_access_token($ck, $cs, $request_token, $verifier, $request_token_secret) {
        $url = 'https://www.tumblr.com/oauth/access_token';

        $oauth_extra = [
            'oauth_verifier' => $verifier,
        ];

        $auth = $this->build_oauth_header('POST', $url, [], $ck, $cs, $request_token, $request_token_secret, $oauth_extra);

        $res = wp_remote_post($url, [
            'timeout' => 30,
            'headers' => [
                'Authorization' => $auth,
            ],
        ]);

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

        $code = wp_remote_retrieve_response_code($res);
        $body = (string) wp_remote_retrieve_body($res);

        if ($code < 200 || $code >= 300) {
            return new WP_Error('tumblr_oauth', 'Error (' . $code . '): could not obtain access token.');
        }

        parse_str($body, $out);
        if (empty($out['oauth_token']) || empty($out['oauth_token_secret'])) {
            return new WP_Error('tumblr_oauth', 'Invalid response while requesting access token.');
        }

        return $out;
    }

    private function build_oauth_header($method, $url, $params, $ck, $cs, $tk = '', $ts = '', $oauth_extra = []) {
        $oauth = [
            'oauth_consumer_key' => $ck,
            'oauth_nonce' => wp_generate_password(12, false),
            'oauth_signature_method' => 'HMAC-SHA1',
            'oauth_timestamp' => time(),
            'oauth_version' => '1.0',
        ];

        if ($tk !== '') {
            $oauth['oauth_token'] = $tk;
        }

        if (is_array($oauth_extra) && !empty($oauth_extra)) {
            foreach ($oauth_extra as $k => $v) {
                $oauth[$k] = $v;
            }
        }

        // Base string = oauth params + request params (query/body)
        $base = array_merge($oauth, is_array($params) ? $params : []);
        unset($base['oauth_signature']);
        ksort($base);

        $parts = [];
        foreach ($base as $k => $v) {
            $parts[] = rawurlencode($k) . '=' . rawurlencode($v);
        }

        $base_str = strtoupper($method) . '&' . rawurlencode($url) . '&' . rawurlencode(implode('&', $parts));
        $key = rawurlencode($cs) . '&' . rawurlencode($ts);

        $oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_str, $key, true));

        $h = [];
        foreach ($oauth as $k => $v) {
            if (strpos($k, 'oauth_') === 0) {
                $h[] = $k . '="' . rawurlencode($v) . '"';
            }
        }

        return 'OAuth ' . implode(', ', $h);
    }

    private function generate_oauth_header($method, $url, $params, $ck, $cs, $tk, $ts) {
        return $this->build_oauth_header($method, $url, $params, $ck, $cs, $tk, $ts);
    }
}

