<?php

if ( !defined( 'ABSPATH' ) ) {
    exit;
}
final class AISBW_Admin_Menu {
    private const CAPABILITY = 'manage_guco_ai_blog_writer';

    private static ?AISBW_Admin_Menu $instance = null;

    private AISBW_Topic_Repository $topics;

    private AISBW_Logger $logger;

    public static function instance() : AISBW_Admin_Menu {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function init() : void {
        add_action( 'admin_menu', [$this, 'register_menu'] );
        add_action( 'admin_init', [$this, 'handle_actions'] );
        add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] );
        add_action( 'admin_print_styles', [$this, 'remove_external_notices'], 999 );
    }

    public function register_menu() : void {
        $robot_icon = 'data:image/svg+xml;base64,' . base64_encode( '<svg fill="currentColor" viewBox="0 -64 640 640" xmlns="http://www.w3.org/2000/svg"><path d="M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z"/></svg>' );
        add_menu_page(
            'Gu&Co AI Blog Writer',
            'Gu&Co AI Blog Writer',
            self::CAPABILITY,
            'aisbw-topics',
            [$this, 'render_topics'],
            $robot_icon,
            58
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Topics', 'guco-ai-blog-writer' ),
            __( 'Topics', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-topics',
            [$this, 'render_topics']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Add Topic', 'guco-ai-blog-writer' ),
            __( 'Add Topic', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-topic-edit',
            [$this, 'render_topic_edit']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Title Suggestions', 'guco-ai-blog-writer' ),
            __( 'Title Suggestions', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-title-suggestions',
            [$this, 'render_title_suggestions']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Import CSV', 'guco-ai-blog-writer' ),
            __( 'Import CSV', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-import',
            [$this, 'render_import']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Generated Drafts', 'guco-ai-blog-writer' ),
            __( 'Generated Drafts', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-drafts',
            [$this, 'render_drafts']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Logs', 'guco-ai-blog-writer' ),
            __( 'Logs', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-logs',
            [$this, 'render_logs']
        );
        add_submenu_page(
            'aisbw-topics',
            __( 'Settings', 'guco-ai-blog-writer' ),
            __( 'Settings', 'guco-ai-blog-writer' ),
            self::CAPABILITY,
            'aisbw-settings',
            [$this, 'render_settings']
        );
    }

    public function enqueue_assets( string $hook ) : void {
        $page = ( isset( $_GET['page'] ) ? sanitize_key( wp_unslash( (string) $_GET['page'] ) ) : '' );
        if ( !str_starts_with( $page, 'aisbw-' ) ) {
            return;
        }
        wp_enqueue_style(
            'aisbw-admin',
            AISBW_PLUGIN_URL . 'assets/admin.css',
            [],
            AISBW_VERSION
        );
        wp_enqueue_script(
            'aisbw-admin',
            AISBW_PLUGIN_URL . 'assets/admin.js',
            ['jquery'],
            AISBW_VERSION,
            true
        );
    }

    public function remove_external_notices() : void {
        $page = ( isset( $_GET['page'] ) ? sanitize_key( wp_unslash( (string) $_GET['page'] ) ) : '' );
        if ( !str_starts_with( $page, 'aisbw-' ) ) {
            return;
        }
        remove_all_actions( 'admin_notices' );
        remove_all_actions( 'user_admin_notices' );
        remove_all_actions( 'all_admin_notices' );
        remove_all_actions( 'network_admin_notices' );
    }

    public function handle_actions() : void {
        if ( !is_admin() || !current_user_can( self::CAPABILITY ) ) {
            return;
        }
        if ( isset( $_POST['aisbw_action'] ) ) {
            $this->handle_post_action( sanitize_key( wp_unslash( (string) $_POST['aisbw_action'] ) ) );
        }
        if ( isset( $_GET['aisbw_action'] ) ) {
            $this->handle_get_action( sanitize_key( wp_unslash( (string) $_GET['aisbw_action'] ) ) );
        }
    }

    public function render_topics() : void {
        $this->require_capability();
        $topics = $this->topics->all( [
            'limit' => 100,
        ] );
        $this->render_view( 'topics', [
            'topics' => $topics,
        ] );
    }

    public function render_topic_edit() : void {
        $this->require_capability();
        $topic_id = ( isset( $_GET['topic_id'] ) ? absint( $_GET['topic_id'] ) : 0 );
        $topic = ( $topic_id ? $this->topics->get( $topic_id ) : null );
        $this->render_view( 'topic-edit', [
            'topic' => $topic,
        ] );
    }

    public function render_import() : void {
        $this->require_capability();
        if ( !aisbw_is_premium() ) {
            $this->render_view( 'pro-only', [
                'feature_name'        => __( 'Import topics from CSV', 'guco-ai-blog-writer' ),
                'feature_description' => __( 'Bulk import of topics from CSV files is only available for Premium version users.', 'guco-ai-blog-writer' ),
                'benefits'            => [__( 'Quickly import dozens of topics with one click', 'guco-ai-blog-writer' ), __( 'Automatic mapping of keywords, target audiences, and priorities', 'guco-ai-blog-writer' ), __( 'Optional topic approval directly after import', 'guco-ai-blog-writer' )],
            ] );
            return;
        }
        $this->render_view( 'import', [] );
    }

    public function render_title_suggestions() : void {
        $this->require_capability();
        if ( !aisbw_is_premium() ) {
            $this->render_view( 'pro-only', [
                'feature_name'        => __( 'AI Topic and Title Suggestions', 'guco-ai-blog-writer' ),
                'feature_description' => __( 'Analysis of existing WordPress articles to find topic gaps and generate new proposals by AI is a Premium feature.', 'guco-ai-blog-writer' ),
                'benefits'            => [__( 'Automatically scan existing WordPress posts to build topic clusters', 'guco-ai-blog-writer' ), __( 'Generate ready-to-use topics with matched target audience, intent, and priorities', 'guco-ai-blog-writer' ), __( 'Easily add selected suggestions to the topic list with one click', 'guco-ai-blog-writer' )],
            ] );
            return;
        }
        $result = get_transient( $this->title_suggestions_transient_key() );
        if ( is_array( $result ) && !empty( $result['suggestions'] ) ) {
            $filtered = [];
            foreach ( $result['suggestions'] as $suggestion ) {
                if ( $this->topics->duplicate_exists( [
                    'topic'           => $suggestion['title'] ?? '',
                    'primary_keyword' => $suggestion['primary_keyword'] ?? '',
                    'working_title'   => $suggestion['title'] ?? '',
                ] ) ) {
                    continue;
                }
                $filtered[] = $suggestion;
            }
            $result['suggestions'] = $filtered;
        }
        $this->render_view( 'title-suggestions', [
            'result' => ( is_array( $result ) ? $result : [] ),
        ] );
    }

    public function render_drafts() : void {
        $this->require_capability();
        $topic_id = ( isset( $_GET['topic_id'] ) ? absint( $_GET['topic_id'] ) : 0 );
        if ( $topic_id ) {
            $topic = $this->topics->get( $topic_id );
            $this->render_view( 'generated-post-preview', [
                'topic' => $topic,
            ] );
            return;
        }
        $topics = $this->topics->list_generated( [
            'limit' => 100,
        ] );
        $this->render_view( 'drafts', [
            'topics' => $topics,
        ] );
    }

    public function render_logs() : void {
        $this->require_capability();
        $logs = $this->logger->all( 250 );
        $this->render_view( 'logs', [
            'logs' => $logs,
        ] );
    }

    public function render_settings() : void {
        $this->require_capability();
        $this->render_view( 'settings', [] );
    }

    public function page_url( string $page, array $args = [] ) : string {
        return add_query_arg( array_merge( [
            'page' => $page,
        ], $args ), admin_url( 'admin.php' ) );
    }

    public function topic_action_url(
        string $action,
        int $topic_id,
        string $page = 'aisbw-topics',
        array $args = []
    ) : string {
        $url = $this->page_url( $page, array_merge( [
            'aisbw_action' => $action,
            'topic_id'     => $topic_id,
        ], $args ) );
        return wp_nonce_url( $url, 'aisbw_topic_action_' . $topic_id );
    }

    public function format_status( string $status ) : string {
        $labels = [
            'idea'             => __( 'Idea', 'guco-ai-blog-writer' ),
            'approved'         => __( 'Approved', 'guco-ai-blog-writer' ),
            'brief_ready'      => __( 'Brief ready', 'guco-ai-blog-writer' ),
            'generating'       => __( 'Generating', 'guco-ai-blog-writer' ),
            'draft_ready'      => __( 'Draft ready', 'guco-ai-blog-writer' ),
            'wp_draft_created' => __( 'WP Draft', 'guco-ai-blog-writer' ),
            'review_required'  => __( 'For review', 'guco-ai-blog-writer' ),
            'scheduled'        => __( 'Scheduled', 'guco-ai-blog-writer' ),
            'published'        => __( 'Published', 'guco-ai-blog-writer' ),
            'rejected'         => __( 'Rejected', 'guco-ai-blog-writer' ),
            'failed'           => __( 'Error', 'guco-ai-blog-writer' ),
        ];
        return $labels[$status] ?? $status;
    }

    public function decode_json( ?string $json ) : array {
        $decoded = json_decode( (string) $json, true );
        return ( is_array( $decoded ) ? $decoded : [] );
    }

    private function handle_post_action( string $action ) : void {
        try {
            if ( 'save_topic' === $action ) {
                $topic_id = ( isset( $_POST['topic_id'] ) ? absint( $_POST['topic_id'] ) : 0 );
                try {
                    $this->save_topic();
                } catch ( Throwable $e ) {
                    $args = [
                        'aisbw_error' => $e->getMessage(),
                    ];
                    if ( $topic_id ) {
                        $args['topic_id'] = $topic_id;
                        $this->redirect( 'aisbw-topic-edit', $args );
                    } else {
                        $this->redirect( 'aisbw-topics', $args );
                    }
                }
                return;
            }
        } catch ( Throwable $e ) {
            $page = ( in_array( $action, ['generate_title_suggestions', 'create_topic_from_suggestion'], true ) ? 'aisbw-title-suggestions' : 'aisbw-topics' );
            $this->redirect( $page, [
                'aisbw_error' => $e->getMessage(),
            ] );
        }
    }

    private function handle_get_action( string $action ) : void {
        $topic_id = ( isset( $_GET['topic_id'] ) ? absint( $_GET['topic_id'] ) : 0 );
        if ( !$topic_id ) {
            return;
        }
        check_admin_referer( 'aisbw_topic_action_' . $topic_id );
        try {
            switch ( $action ) {
                case 'approve':
                    $this->topics->update_status( $topic_id, 'approved' );
                    $this->logger->info(
                        'topic_approved',
                        'Temat zatwierdzony.',
                        [],
                        $topic_id
                    );
                    $this->redirect( 'aisbw-topics', [
                        'aisbw_notice' => __( 'Topic approved.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'reject':
                    $this->topics->update_status( $topic_id, 'rejected' );
                    $this->logger->info(
                        'topic_rejected',
                        'Temat odrzucony.',
                        [],
                        $topic_id
                    );
                    $this->redirect( 'aisbw-topics', [
                        'aisbw_notice' => __( 'Topic rejected.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'delete':
                    $this->topics->delete( $topic_id );
                    $this->logger->info(
                        'topic_deleted',
                        'Temat usunięty.',
                        [],
                        $topic_id
                    );
                    $this->redirect( 'aisbw-topics', [
                        'aisbw_notice' => __( 'Topic deleted.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'generate_brief':
                    ( new AISBW_Content_Generator($this->topics) )->generate_brief( $topic_id );
                    $this->redirect( 'aisbw-topics', [
                        'aisbw_notice' => __( 'Brief generated.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'generate_article':
                case 'regenerate':
                    ( new AISBW_Content_Generator($this->topics) )->generate_article( $topic_id );
                    ( new AISBW_Quality_Checker($this->topics) )->check( $topic_id );
                    $this->redirect( 'aisbw-drafts', [
                        'topic_id'     => $topic_id,
                        'aisbw_notice' => __( 'Article generated and evaluated.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'quality_check':
                    ( new AISBW_Quality_Checker($this->topics) )->check( $topic_id );
                    $this->redirect( 'aisbw-drafts', [
                        'topic_id'     => $topic_id,
                        'aisbw_notice' => __( 'Quality check completed.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
                case 'create_wp_draft':
                    $post_id = ( new AISBW_Post_Creator($this->topics) )->create_from_topic( $topic_id );
                    $this->redirect( 'aisbw-drafts', [
                        'topic_id'     => $topic_id,
                        'aisbw_notice' => sprintf( __( 'WP post #%s created.', 'guco-ai-blog-writer' ), $post_id ),
                    ] );
                    break;
                case 'regenerate_featured_image':
                    $this->regenerate_featured_image_action( $topic_id );
                    $this->redirect( 'aisbw-drafts', [
                        'topic_id'     => $topic_id,
                        'aisbw_notice' => __( 'Featured image regenerated successfully.', 'guco-ai-blog-writer' ),
                    ] );
                    break;
            }
        } catch ( Throwable $e ) {
            $topic = $this->topics->get( $topic_id );
            $page = ( $topic && !empty( $topic['generated_content'] ) ? 'aisbw-drafts' : 'aisbw-topics' );
            $args = [
                'aisbw_error' => $e->getMessage(),
            ];
            if ( 'aisbw-drafts' === $page ) {
                $args['topic_id'] = $topic_id;
            }
            $this->redirect( $page, $args );
        }
    }

    private function save_topic() : void {
        check_admin_referer( 'aisbw_save_topic' );
        $topic_id = ( isset( $_POST['topic_id'] ) ? absint( $_POST['topic_id'] ) : 0 );
        $data = $this->topic_payload( $_POST );
        if ( '' === $data['topic'] ) {
            throw new RuntimeException(__( 'Topic is required.', 'guco-ai-blog-writer' ));
        }
        if ( $this->topics->duplicate_exists( $data, ( $topic_id ?: null ) ) ) {
            throw new RuntimeException(__( 'A similar topic, slug, or primary keyword already exists.', 'guco-ai-blog-writer' ));
        }
        if ( $topic_id ) {
            $this->topics->update( $topic_id, $data );
            $this->logger->info(
                'topic_updated',
                'Temat zaktualizowany.',
                [],
                $topic_id
            );
            $this->redirect( 'aisbw-topic-edit', [
                'topic_id'     => $topic_id,
                'aisbw_notice' => __( 'Topic updated.', 'guco-ai-blog-writer' ),
            ] );
        }
        $topic_id = $this->topics->create( $data );
        $this->logger->info(
            'topic_created',
            'Temat utworzony.',
            [],
            $topic_id
        );
        $this->redirect( 'aisbw-topic-edit', [
            'topic_id'     => $topic_id,
            'aisbw_notice' => __( 'Topic added.', 'guco-ai-blog-writer' ),
        ] );
    }

    private function suggestion_tags( string $primary_keyword, string $secondary_keywords ) : string {
        $tags = [];
        if ( '' !== trim( $primary_keyword ) ) {
            $tags[] = trim( $primary_keyword );
        }
        if ( '' !== trim( $secondary_keywords ) ) {
            $tags = array_merge( $tags, array_map( 'trim', explode( ',', $secondary_keywords ) ) );
        }
        $tags = array_filter( array_unique( array_map( 'sanitize_text_field', $tags ) ) );
        return implode( ', ', array_slice( $tags, 0, 8 ) );
    }

    private function topic_payload( array $source ) : array {
        $payload = [];
        foreach ( [
            'topic',
            'working_title',
            'primary_keyword',
            'audience',
            'search_intent',
            'tags',
            'risk_level',
            'publish_mode',
            'language',
            'status'
        ] as $field ) {
            $payload[$field] = ( isset( $source[$field] ) ? sanitize_text_field( wp_unslash( (string) $source[$field] ) ) : '' );
        }
        foreach ( ['secondary_keywords', 'notes'] as $field ) {
            $payload[$field] = ( isset( $source[$field] ) ? sanitize_textarea_field( wp_unslash( (string) $source[$field] ) ) : '' );
        }
        $payload['category_id'] = ( isset( $source['category_id'] ) ? absint( $source['category_id'] ) : 0 );
        $payload['priority'] = ( isset( $source['priority'] ) ? absint( $source['priority'] ) : 50 );
        if ( isset( $source['brief'] ) ) {
            $brief_raw = wp_unslash( (string) $source['brief'] );
            if ( '' !== trim( $brief_raw ) ) {
                $decoded = json_decode( $brief_raw, true );
                if ( null === $decoded ) {
                    throw new RuntimeException(__( 'Provided brief is not a valid JSON.', 'guco-ai-blog-writer' ));
                }
                $payload['brief'] = wp_json_encode( $decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
            } else {
                $payload['brief'] = null;
            }
        }
        return $payload;
    }

    private function render_view( string $view, array $vars ) : void {
        $this->notices();
        extract( $vars, EXTR_SKIP );
        include AISBW_PLUGIN_DIR . 'admin/views/' . $view . '.php';
    }

    private function notices() : void {
        if ( isset( $_GET['aisbw_notice'] ) ) {
            $message = sanitize_text_field( wp_unslash( (string) $_GET['aisbw_notice'] ) );
            printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( $message ) );
        }
        if ( isset( $_GET['aisbw_error'] ) ) {
            $message = sanitize_text_field( wp_unslash( (string) $_GET['aisbw_error'] ) );
            printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html( $message ) );
        }
    }

    private function redirect( string $page, array $args = [] ) : void {
        wp_safe_redirect( $this->page_url( $page, $args ) );
        exit;
    }

    private function title_suggestions_transient_key() : string {
        return 'aisbw_title_suggestions_' . get_current_user_id();
    }

    private function require_capability() : void {
        if ( !current_user_can( self::CAPABILITY ) ) {
            wp_die( esc_html__( 'You do not have permission to manage Gu&Co AI Blog Writer.', 'guco-ai-blog-writer' ) );
        }
    }

    private function regenerate_featured_image_action( int $topic_id ) : void {
        $topic = $this->topics->get( $topic_id );
        if ( !$topic ) {
            throw new RuntimeException(__( 'Topic not found.', 'guco-ai-blog-writer' ));
        }
        $article = $this->decode_json( $topic['generated_content'] ?? '' );
        $title = (string) ($article['title'] ?? $topic['working_title'] ?? $topic['topic']);
        if ( empty( $title ) ) {
            throw new RuntimeException(__( 'Cannot generate image: article title is missing.', 'guco-ai-blog-writer' ));
        }
        $post_id = ( !empty( $topic['wp_post_id'] ) ? (int) $topic['wp_post_id'] : 0 );
        if ( !$post_id ) {
            if ( !empty( $article ) ) {
                ( new AISBW_Post_Creator($this->topics) )->create_from_topic( $topic_id );
                return;
            } else {
                throw new RuntimeException(__( 'Please generate the article first before creating a featured image.', 'guco-ai-blog-writer' ));
            }
        }
        if ( class_exists( 'AISBW_Featured_Image_Premium' ) ) {
            AISBW_Featured_Image_Premium::generate_for_post( $post_id, $title );
            $this->logger->info(
                'featured_image_regenerated',
                'Wygenerowano ponownie obrazek wyróżniający wpisu.',
                [
                    'post_id' => $post_id,
                ],
                $topic_id
            );
        } else {
            throw new RuntimeException(__( 'Featured image generator class not available.', 'guco-ai-blog-writer' ));
        }
    }

    private function __construct() {
        $this->topics = new AISBW_Topic_Repository();
        $this->logger = new AISBW_Logger();
    }

}
