<?php
defined( 'ABSPATH' ) || exit;

class NASEO_AI_Generator {

    private string $api_key;
    private string $model   = 'claude-sonnet-4-5';
    private string $api_url = 'https://api.anthropic.com/v1/messages';

    public function __construct() {
        $this->api_key = get_option( 'naseo_claude_api_key', '' );
    }

    public function generate( array $item ) {
        if ( empty( $this->api_key ) ) {
            NASEO_Logger::log( 'error', 'Claude API: ключ не вказано.' );
            return false;
        }

        $result = $this->generate_combined( $item );
        if ( ! $result ) return false;

        return $result;
    }

    private function generate_combined( array $item ) {
        $language = get_option( 'naseo_language', 'uk' );
        $sitename = get_bloginfo( 'name' );
        $year     = gmdate( 'Y' );
        $custom   = get_option( 'naseo_custom_prompt', '' );

        if ( $custom ) {
            $article_prompt = strtr( $custom, [
                '{TITLE}'        => $item['title'],
                '{KEYWORD}'      => $item['keyword'],
                '{LSI_KEYWORDS}' => $item['lsi_keywords'] ?? '',
                '{LANGUAGE}'     => $language,
                '{SITE_NAME}'    => $sitename,
                '{YEAR}'         => $year,
            ] );
        } else {
            $lsi = ! empty( $item['lsi_keywords'] ) ? $item['lsi_keywords'] : '';

            $article_prompt = "Ти професійний SEO-копірайтер, який пише так, наче текст створила людина.
Твоє завдання — написати SEO-оптимізовану статтю мовою: {$language} для сайту {$sitename}.

Тема: {$item['title']}

🔑 Вимоги:
- Використовуй основне ключове слово: {$item['keyword']} — 3-5 разів у тексті природно.
- Додай LSI-ключі: {$lsi} — вплети органічно." . "
- Обов'язково зроби:
  • Один <h1> — заголовок, що містить ключове слово (ВАЖЛИВО: не повторюй h1 в тілі статті)
  • 4-6 підрозділів <h2> з варіаціями ключових фраз
  • Де потрібно — <h3>, <ul>, <ol>, <strong>
  • Обгортай абзаци в <p>
  • Вступ: 3-4 речення, чіпляючий, без фрази «У цій статті ми розглянемо»
  • Структурований текст: списки, факти, приклади, порівняння
  • Невеликий висновок із call-to-action
  • ВАЖЛИВО: після першого <h2> встав плейсхолдер {{IMAGE_1}}, після третього <h2> встав {{IMAGE_2}}

🎯 Стиль:
- Пиши від третьої особи або безособово — як журналіст або оглядач, НЕ від першої особи (без «я», «ми», «мій», «наш»).
- Легка, розмовна мова, наче блогер ділиться досвідом.
- Жодної канцелярщини, текст має бути живим і цікавим.
- Додавай приклади, лайфхаки та порівняння з реального життя.
- Використовуй перехідні слова («по-перше», «з іншого боку», «але є нюанс», «і ось тут починається цікаве»).
- Уникай одноманітності та повторів.
- Чергуй короткі і довгі речення для живого ритму.
- Уникай кліше: «варто зазначити», «слід відмітити», «безумовно», «таким чином», «в цілому», «підводячи підсумок».
- НЕ починай абзаци з однакових слів.

📏 Обсяг: 4000–5000 символів.
📄 Формат відповіді: чистий HTML, тільки контент (без DOCTYPE, html, head, body, meta тегів).";
        }

        // Запит 1 — стаття
        $article = $this->call_api( $article_prompt, 8000 );
        if ( ! $article ) return false;

        // Запит 2 — SEO JSON
        $keyword = sanitize_text_field( $item['keyword'] );
        $title   = sanitize_text_field( $item['title'] );

        $seo_prompt = "Створи SEO-метадані мовою {$language} для статті нижче.

Заголовок: {$title}
Ключове слово: {$keyword}

Правила:
- seo_title: містить \"{$keyword}\", 50-60 символів, без дужок
- meta_description: містить \"{$keyword}\", 130-155 символів, без дужок
- focus_keyphrase: рівно \"{$keyword}\" — нічого більше
- og_title і twitter_title: до 60 символів
- og_description і twitter_description: до 200 символів
- tags: масив з 5 рядків, кожен — реальне слово або фраза

Поверни ТІЛЬКИ JSON. Без пояснень. Без ```json. Без тексту до або після.

Приклад формату:
{\"seo_title\":\"Приклад заголовку з ключем {$year}\",\"meta_description\":\"Приклад опису з ключовим словом {$keyword}. Практичні поради та реальні приклади.\",\"focus_keyphrase\":\"{$keyword}\",\"og_title\":\"Приклад og заголовку\",\"og_description\":\"Приклад og опису\",\"twitter_title\":\"Приклад twitter заголовку\",\"twitter_description\":\"Приклад twitter опису\",\"tags\":[\"{$keyword}\",\"тег2\",\"тег3\",\"тег4\",\"тег5\"]}

Стаття для аналізу:
" . mb_substr( $article, 0, 2000 );

        $raw_seo = $this->call_api( $seo_prompt, 600 );
        if ( ! $raw_seo ) return false;

        // Чистимо відповідь
        $raw_seo = trim( $raw_seo );
        $raw_seo = preg_replace( '/^```json\s*/i', '', $raw_seo );
        $raw_seo = preg_replace( '/^```\s*/i', '', $raw_seo );
        $raw_seo = preg_replace( '/\s*```$/i', '', $raw_seo );

        if ( preg_match( '/\{.*\}/s', $raw_seo, $matches ) ) {
            $raw_seo = $matches[0];
        }

        $seo = json_decode( $raw_seo, true );

        if ( ! is_array( $seo ) ) {
            NASEO_Logger::log( 'error', 'SEO JSON parse error: ' . mb_substr( $raw_seo, 0, 300 ) );
            return [
                'content'             => $article,
                'seo_title'           => mb_substr( $title, 0, 60 ),
                'meta_description'    => mb_substr( $title, 0, 155 ),
                'focus_keyphrase'     => $keyword,
                'og_title'            => mb_substr( $title, 0, 60 ),
                'og_description'      => mb_substr( $title, 0, 200 ),
                'twitter_title'       => mb_substr( $title, 0, 60 ),
                'twitter_description' => mb_substr( $title, 0, 200 ),
                'tags'                => explode( ',', $keyword ),
            ];
        }

        $seo['focus_keyphrase'] = $keyword;

        foreach ( $seo as $k => $v ) {
            if ( is_string( $v ) && preg_match( '/^\(.*\)$/', trim( $v ) ) ) {
                $seo[ $k ] = $k === 'focus_keyphrase' ? $keyword : mb_substr( $title, 0, 60 );
            }
        }

        $seo['content'] = $article;
        return $seo;
    }

    private function call_api( string $prompt, int $max_tokens ) {
        $response = wp_remote_post( $this->api_url, [
            'timeout' => 120,
            'headers' => [
                'Content-Type'      => 'application/json',
                'x-api-key'         => $this->api_key,
                'anthropic-version' => '2023-06-01',
            ],
            'body' => wp_json_encode( [
                'model'      => $this->model,
                'max_tokens' => $max_tokens,
                'messages'   => [ [ 'role' => 'user', 'content' => $prompt ] ],
            ] ),
        ] );

        if ( is_wp_error( $response ) ) {
            NASEO_Logger::log( 'error', 'Claude API (мережева помилка): ' . $response->get_error_message() );
            return false;
        }

        $code     = (int) wp_remote_retrieve_response_code( $response );
        $raw_body = wp_remote_retrieve_body( $response );
        $body     = json_decode( $raw_body, true );

        if ( $code !== 200 ) {
            $msg = $body['error']['message'] ?? ( 'HTTP ' . $code . ' — ' . mb_substr( $raw_body, 0, 300 ) );
            NASEO_Logger::log( 'error', 'Claude API (HTTP ' . $code . '): ' . $msg );
            return false;
        }

        $text = $body['content'][0]['text'] ?? '';

        if ( empty( $text ) ) {
            NASEO_Logger::log( 'error', 'Claude API: порожня відповідь. stop_reason=' . ( $body['stop_reason'] ?? '?' ) );
            return false;
        }

        return $text;
    }
}
