<?php

namespace Pixalia\ImageAssistant\Admin\View;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Pixalia\ImageAssistant\Base\Const\MetaKeyConst;
use Pixalia\ImageAssistant\Base\Const\PixaliaConst;

/**
 * 投稿一覧にステータスタブを追加するクラス
 */
class PostListStatusTabs {

    private const CACHE_KEY_PREFIX = 'pixalia_status_counts_';
    private const CACHE_EXPIRATION = 3600;

    public function __construct() {
        add_filter( 'views_edit-post', [ $this, 'add_status_tabs' ] );
        add_filter( 'views_edit-page', [ $this, 'add_status_tabs' ] );
        add_action( 'pre_get_posts', [ $this, 'filter_by_status_tab' ] );
    }

    /**
     * ステータスタブを追加
     */
    public function add_status_tabs( array $views ): array {
        $screen = get_current_screen();
        if ( ! $screen ) {
            return $views;
        }

        $post_type      = $screen->post_type;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- 投稿一覧の表示用（GET）のためNonce確認は不要
        $current_status = isset( $_GET['pixalia_status'] ) ? sanitize_text_field( wp_unslash( $_GET['pixalia_status'] ) ) : '';
        $counts = $this->get_status_counts( $post_type );

        $status_tabs = [
                'ok'      => [
                        'label' => __( 'OK', 'pixalia-image-assistant' ),
                        'icon'  => '✓',
                        'color' => '#00a32a',
                        'count' => $counts['ok'],
                ],
                'warning' => [
                        'label' => __( 'Warning', 'pixalia-image-assistant' ),
                        'icon'  => '⚠',
                        'color' => '#dba617',
                        'count' => $counts['warning'],
                ],
                'ng'      => [
                        'label' => __( 'NG', 'pixalia-image-assistant' ),
                        'icon'  => '✕',
                        'color' => '#d63638',
                        'count' => $counts['ng'],
                ],
        ];

        // ★ 改行用のダミーエントリを追加
        $has_pixalia_tabs = false;
        foreach ( $status_tabs as $data ) {
            if ( $data['count'] > 0 ) {
                $has_pixalia_tabs = true;
                break;
            }
        }

        if ( $has_pixalia_tabs ) {
            // ★ 改行を挿入（force_breakというキー）
            $views['pixalia_break'] = '';
        }

        // タブのHTMLを生成
        foreach ( $status_tabs as $status => $data ) {
            if ( $data['count'] === 0 ) {
                continue;
            }

            $url = add_query_arg( [
                    'post_type'      => $post_type,
                    'pixalia_status' => $status,
            ], admin_url( 'edit.php' ) );

            $class = ( $current_status === $status ) ? 'current' : '';

            $views[ 'pixalia_' . $status ] = sprintf(
                    '<a href="%s" class="%s" style="color: %s;">%s %s <span class="count">(%d)</span></a>',
                    esc_url( $url ),
                    esc_attr( $class ),
                    esc_attr( $data['color'] ),
                    $data['icon'],
                    esc_html( $data['label'] ),
                    $data['count']
            );
        }

        return $views;
    }

    /**
     * タブクリック時のフィルタリング処理
     */
    public function filter_by_status_tab( \WP_Query $query ): void {
        if ( ! is_admin() || ! $query->is_main_query() ) {
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- フィルタリング処理（GET）のためNonce確認は不要
        $status = isset( $_GET['pixalia_status'] ) ? sanitize_text_field( wp_unslash( $_GET['pixalia_status'] ) ) : '';

        if ( empty( $status ) ) {
            return;
        }

        if ( 'unchecked' === $status ) {
            $query->set( 'meta_query', [
                    [
                            'key'     => MetaKeyConst::ImageStatus,
                            'compare' => 'NOT EXISTS',
                    ],
            ] );
        } else {
            $query->set( 'meta_key', MetaKeyConst::ImageStatus );
            $query->set( 'meta_value', $status );
        }
    }

    /**
     * ステータスごとの件数を取得（キャッシュ付き）
     */
    private function get_status_counts( string $post_type ): array {
        $cache_key = self::CACHE_KEY_PREFIX . $post_type;
        $counts = get_transient( $cache_key );

        if ( false !== $counts && is_array( $counts ) ) {
            return $counts;
        }

        $counts = $this->query_status_counts( $post_type );
        set_transient( $cache_key, $counts, self::CACHE_EXPIRATION );

        return $counts;
    }

    /**
     * DBから実際にステータスごとの件数を取得
     */
    private function query_status_counts( string $post_type ): array {
        global $wpdb;

        $allowed_types = get_option( PixaliaConst::OPTION_POST_TYPES, [ 'post' ] );
        if ( ! in_array( $post_type, $allowed_types, true ) ) {
            return [
                    'ok'        => 0,
                    'warning'   => 0,
                    'ng'        => 0,
                    'unchecked' => 0,
            ];
        }
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- 集計(GROUP BY)のため直接SQLが必要。キャッシュは呼び出し元(get_status_counts)でTransientにて実装済み。
        $results = $wpdb->get_results( $wpdb->prepare( "
            SELECT 
                COALESCE(pm.meta_value, 'unchecked') as status, 
                COUNT(*) as count
            FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} pm 
                ON p.ID = pm.post_id 
                AND pm.meta_key = %s
            WHERE p.post_type = %s
                AND p.post_status NOT IN ('trash', 'auto-draft')
            GROUP BY COALESCE(pm.meta_value, 'unchecked')
        ", MetaKeyConst::ImageStatus, $post_type ), OBJECT_K );

        return [
                'ok'        => isset( $results['ok'] ) ? (int) $results['ok']->count : 0,
                'warning'   => isset( $results['warning'] ) ? (int) $results['warning']->count : 0,
                'ng'        => isset( $results['ng'] ) ? (int) $results['ng']->count : 0,
                'unchecked' => isset( $results['unchecked'] ) ? (int) $results['unchecked']->count : 0,
        ];
    }

    /**
     * キャッシュをクリア
     */
    public static function clear_cache( string $post_type ): void {
        delete_transient( self::CACHE_KEY_PREFIX . $post_type );
    }
}
