<?php

namespace XZD\AI\V5\Theme;

/**
 * 主题适配器基类 — 所有方法返回安全默认值，子类只需覆盖需要的部分
 */
abstract class AdapterBase implements AdapterInterface
{
    // 身份信息 (子类必须覆盖)
    public function getThemeName(): string    { return '通用主题'; }
    public function getThemeVersion(): string  { return '0.0'; }
    public function isDarkMode(): bool         { return false; }

    // 能力声明
    public function getCapabilities(): array
    {
        return [
            'points'       => ['available' => true, 'reason' => '', 'source' => 'wp_usermeta(xzd_points)'],
            'balance'      => ['available' => true, 'reason' => '', 'source' => 'wp_usermeta(xzd_balance)'],
            'vip'          => ['available' => false, 'reason' => '当前主题不支持VIP系统', 'source' => '—'],
            'blacklist'    => ['available' => false, 'reason' => '当前主题不支持封禁功能', 'source' => '—'],
            'medal'        => ['available' => false, 'reason' => '当前主题不支持勋章系统', 'source' => '—'],
            'notification' => ['available' => true, 'reason' => '', 'source' => 'wp_usermeta(xzd_notifications)'],
            'checkin'      => ['available' => false, 'reason' => '当前主题不支持签到系统', 'source' => '—'],
            'invite'       => ['available' => false, 'reason' => '当前主题不支持邀请系统', 'source' => '—'],
            'order'        => ['available' => false, 'reason' => '当前主题不支持订单系统', 'source' => '—'],
            'bbs'          => ['available' => false, 'reason' => '当前主题不支持论坛系统', 'source' => '—'],
        ];
    }

    // 积分系统 — 默认使用 wp_usermeta 存储（无主题依赖）
    public function getPoints(int $userId): int
    {
        return (int) get_user_meta($userId, 'xzd_points', true);
    }

    public function addPoints(int $userId, int $amount, string $reason, int $operatorId): array
    {
        $before = $this->getPoints($userId);
        update_user_meta($userId, 'xzd_points', $before + $amount);
        return $this->ok('积分增加成功', ['before' => $before, 'after' => $before + $amount]);
    }

    public function deductPoints(int $userId, int $amount, string $reason, int $operatorId): array
    {
        $before = $this->getPoints($userId);
        $after = max(0, $before - $amount);
        update_user_meta($userId, 'xzd_points', $after);
        return $this->ok('积分扣除成功', ['before' => $before, 'after' => $after]);
    }

    // 余额系统
    public function getBalance(int $userId): float
    {
        return 0.0;
    }

    public function addBalance(int $userId, float $amount, string $reason, int $operatorId): array
    {
        return $this->notSupported('余额系统');
    }

    public function deductBalance(int $userId, float $amount, string $reason, int $operatorId): array
    {
        return $this->notSupported('余额系统');
    }

    // VIP 系统
    public function getVipLevel(int $userId): int
    {
        return 0;
    }

    public function setVipLevel(int $userId, int $level, int $days): array
    {
        return $this->notSupported('VIP系统');
    }

    public function removeVip(int $userId): array
    {
        return $this->notSupported('VIP系统');
    }

    // 封禁/黑名单
    public function isBanned(int $userId): bool
    {
        return false;
    }

    public function banUser(int $userId, string $reason, int $operatorId): array
    {
        return $this->notSupported('封禁功能');
    }

    public function unbanUser(int $userId, int $operatorId): array
    {
        return $this->notSupported('封禁功能');
    }

    // 通知系统 — 默认使用 wp_usermeta 存储通知
    public function sendNotification(int $userId, string $title, string $content, int $senderId): array
    {
        $notifications = get_user_meta($userId, 'xzd_notifications', true) ?: [];
        $notifications[] = [
            'title' => $title, 'content' => $content,
            'created_at' => current_time('mysql'), 'read' => false,
        ];
        if (count($notifications) > 50) $notifications = array_slice($notifications, -50);
        update_user_meta($userId, 'xzd_notifications', $notifications);
        return $this->ok('通知已发送');
    }

    public function sendBulkNotification(array $userIds, string $title, string $content, int $operatorId): array
    {
        $sent = 0;
        foreach ($userIds as $uid) {
            $r = $this->sendNotification($uid, $title, $content, $operatorId);
            if ($r['success']) $sent++;
        }
        return $this->ok("已向 {$sent} 个用户发送通知");
    }

    public function sendWebhook(string $url, array $payload, string $event): array
    {
        return $this->notSupported('Webhook');
    }

    // 签到系统
    public function getCheckinStatus(int $userId): array
    {
        return ['checked_in' => false, 'reason' => '当前主题不支持签到'];
    }

    public function doCheckin(int $userId): array
    {
        return $this->notSupported('签到系统');
    }

    // 勋章系统
    public function getMedals(int $userId): array
    {
        return [];
    }

    public function addMedal(int $userId, string $medalId): array
    {
        return $this->notSupported('勋章系统');
    }

    public function removeMedal(int $userId, string $medalId): array
    {
        return $this->notSupported('勋章系统');
    }

    // 邀请系统
    public function getInviteStats(int $userId): array
    {
        return ['invited_count' => 0, 'reason' => '当前主题不支持邀请系统'];
    }

    // 订单系统
    public function getOrders(int $userId, int $limit): array
    {
        return [];
    }

    public function getShopProducts(int $limit): array
    {
        return [];
    }

    public function getProductDetail(int $productId): array
    {
        return [];
    }

    public function getVipLevels(): array
    {
        return [];
    }

    public function getPointsConfig(): array
    {
        return [];
    }

    // 论坛系统
    public function getForumTopics(int $userId, int $limit): array
    {
        return [];
    }

    public function getForumPlates(array $params): array
    {
        return [];
    }

    public function searchForumTopics(string $keyword, int $limit, int $offset): array
    {
        return [];
    }

    public function getForumStats(): array
    {
        return ['total_topics' => 0, 'total_replies' => 0, 'total_plates' => 0];
    }

    // UI 适配
    public function getThemeColors(): array
    {
        return [
            'primary'   => '#0073aa',
            'danger'    => '#dc3232',
            'success'   => '#46b450',
            'warning'   => '#ffb900',
            'dark_bg'   => '#1e1e1e',
            'dark_text' => '#f0f0f0',
            'light_bg'  => '#ffffff',
            'light_text'=> '#333333',
        ];
    }

    public function getBubblePosition(): array
    {
        return [
            'bottom' => '80px',
            'right'  => '20px',
        ];
    }

    public function getButtonContainerSelector(): ?string
    {
        return null;
    }

    public function hasIntegratedButton(): bool
    {
        return false;
    }

    public function getPageContextRules(): array
    {
        return [
            'postIdPattern' => '/postid-(\d+)|post-(\d+)/',
            'forumClass'    => 'single-forum_post',
        ];
    }

    // Gutenberg 块映射 (WP核心块作为默认降级)

    public function getBlockMapping(): array
    {
        return [
            'paragraph'      => 'core/paragraph',
            'heading'        => 'core/heading',
            'list'           => 'core/list',
            'quote'          => 'core/quote',
            'code'           => 'core/code',
            'image'          => 'core/image',
            'table'          => 'core/table',
            'preformatted'   => 'core/preformatted',
            'separator'      => 'core/separator',
            'pullquote'      => 'core/pullquote',
            'details'        => 'core/details',
            'alert'          => '',                    // 不支持，降级
            'styled_heading' => 'core/heading',
            'code_highlight' => 'core/code',
            'styled_quote'   => 'core/quote',
            'feature_card'   => '',
            'collapse'       => 'core/details',
            'button_group'   => '',
            'post_card'      => '',
            'post_list'      => '',
            'seamless_img'   => 'core/image',
        ];
    }

    public function buildBlock(string $abstractType, array $data): array
    {
        $content = $data['content'] ?? '';
        $innerBlocks = $data['innerBlocks'] ?? [];

        switch ($abstractType) {
            case 'paragraph':
                return $this->mkBlock('core/paragraph', $data['attrs'] ?? [], '<p>' . $content . '</p>');

            case 'heading':
                $level = $data['level'] ?? 2;
                $anchor = $data['anchor'] ?? '';
                $idAttr = $anchor ? ' id="' . esc_attr($anchor) . '"' : '';
                return $this->mkBlock('core/heading', ['level' => $level],
                    '<h' . $level . ' class="wp-block-heading"' . $idAttr . '>' . $content . '</h' . $level . '>');

            case 'styled_heading':
                return $this->buildBlock('heading', $data);

            case 'list':
                $ordered = !empty($data['ordered']);
                $items = $data['items'] ?? [];
                if (!empty($items) && is_string($items[0] ?? null)) {
                    $items = array_map(fn($s) => ['content' => $s], $items);
                }
                $tag = $ordered ? 'ol' : 'ul';
                $html = "<{$tag} class=\"wp-block-list\">";
                $childBlocks = [];
                foreach ($items as $item) {
                    $it = is_array($item) ? ($item['content'] ?? '') : $item;
                    $li = $this->mkBlock('core/list-item', [], '<li>' . $it . '</li>');
                    $childBlocks[] = $li;
                    $html .= "\n" . $li['innerHTML'];
                }
                $html .= "\n</{$tag}>";
                return $this->mkBlockWithChildren('core/list', $ordered ? ['ordered' => true] : [], $html, $childBlocks);

            case 'quote':
            case 'styled_quote':
                $citation = $data['citation'] ?? '';
                $html = '<blockquote class="wp-block-quote"><p>' . $content . '</p>';
                if ($citation) $html .= '<cite>' . $citation . '</cite>';
                $html .= '</blockquote>';
                return $this->mkBlock('core/quote', [], $html);

            case 'code':
            case 'code_highlight':
                $escaped = esc_html($data['code'] ?? $content);
                return $this->mkBlock('core/code', [],
                    '<pre class="wp-block-code"><code>' . $escaped . '</code></pre>');

            case 'image':
                $id = (int) ($data['id'] ?? 0);
                $url = $data['url'] ?? '';
                $alt = $data['alt'] ?? '';
                $caption = $data['caption'] ?? '';
                $align = $data['align'] ?? '';
                $alignClass = $align ? ' align' . $align : '';
                $html = '<figure class="wp-block-image size-full' . $alignClass . '">'
                    . '<img src="' . esc_url($url) . '" alt="' . esc_attr($alt) . '" class="wp-image-' . $id . '"/>';
                if ($caption) $html .= '<figcaption class="wp-element-caption">' . esc_html($caption) . '</figcaption>';
                $html .= '</figure>';
                return $this->mkBlock('core/image', ['id' => $id, 'sizeSlug' => 'full', 'linkDestination' => 'none'], $html);

            case 'table':
                $headers = $data['headers'] ?? [];
                $rows = $data['rows'] ?? [];
                $html = '<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr>';
                foreach ($headers as $h) $html .= '<th>' . esc_html($h) . '</th>';
                $html .= '</tr></thead><tbody>';
                foreach ($rows as $row) {
                    $html .= '<tr>';
                    foreach ((array) $row as $cell) $html .= '<td>' . esc_html($cell) . '</td>';
                    $html .= '</tr>';
                }
                $html .= '</tbody></table></figure>';
                return $this->mkBlock('core/table', ['hasFixedLayout' => true], $html);

            case 'separator':
                return $this->mkBlock('core/separator', [],
                    '<hr class="wp-block-separator has-alpha-channel-opacity"/>');

            case 'preformatted':
                return $this->mkBlock('core/preformatted', [],
                    '<pre class="wp-block-preformatted">' . esc_html($content) . '</pre>');

            case 'pullquote':
                $citation = $data['citation'] ?? '';
                $html = '<figure class="wp-block-pullquote"><blockquote><p>' . $content . '</p>';
                if ($citation) $html .= '<cite>' . $citation . '</cite>';
                $html .= '</blockquote></figure>';
                return $this->mkBlock('core/pullquote', [], $html);

            case 'details':
                $summary = $data['summary'] ?? '详情';
                $html = '<details class="wp-block-details"><summary>' . esc_html($summary) . '</summary>';
                $html .= $this->renderInnerBlocks($innerBlocks);
                $html .= '</details>';
                return $this->mkBlockWithChildren('core/details', [], $html, $innerBlocks);

            case 'collapse':
                $title = $data['title'] ?? '展开';
                $childContent = $data['content'] ?? $content;
                if (is_array($childContent)) $childContent = $this->renderInnerBlocks($childContent);
                return $this->mkBlock('core/details', [],
                    '<details class="wp-block-details"><summary>' . esc_html($title) . '</summary>' . $childContent . '</details>');

            case 'alert':
                $style = $data['style'] ?? 'info';
                return $this->mkBlock('core/paragraph', [],
                    '<p><strong>【' . esc_html($style) . '】</strong> ' . $content . '</p>');

            default:
                if (!empty($content)) {
                    return $this->mkBlock('core/paragraph', [], '<p>' . $content . '</p>');
                }
                return [];
        }
    }

    public function getAIBlockGuidelines(): string
    {
        return "支持的块类型:\n"
            . "paragraph: 段落\nheading(level=2|3): 标题\n"
            . "list(ordered=false,items=[]): 列表\n"
            . "quote: 引用\ncode(code=\"...\",language=\"...\"): 代码\n"
            . "table(headers=[],rows=[]): 表格\nseparator: 分隔线\n"
            . "pullquote: 突出引用\npreformatted: 预格式化\n"
            . "规则: 第一个块用heading level=2做标题, 代码用code块";
    }

    public function getTextBlockNames(): array
    {
        return ['core/paragraph', 'core/heading', 'core/quote',
            'core/list', 'core/preformatted', 'core/pullquote'];
    }

    public function getEditorBlockConfig(): array
    {
        return [
            'textBlocks'        => $this->getTextBlockNames(),
            'hasStyledHeading'  => false,
            'hasCodeHighlight'  => false,
            'hasStyledQuote'    => false,
            'hasAlert'          => false,
            'hasFeatureCard'    => false,
            'hasCollapse'       => false,
            'hasButtonGroup'    => false,
            'hasPostCard'       => false,
            'hasPostList'       => false,
            'hasSeamlessImg'    => false,
            'quickInsertBlocks' => [],
            'aiGuidelines'      => $this->getAIBlockGuidelines(),
        ];
    }

    // 内部块构建辅助

    protected function mkBlock(string $name, array $attrs, string $innerHTML): array
    {
        return [
            'blockName'    => $name,
            'attrs'        => $attrs,
            'innerBlocks'  => [],
            'innerHTML'    => $innerHTML,
            'innerContent' => [$innerHTML],
        ];
    }

    protected function mkBlockWithChildren(string $name, array $attrs, string $innerHTML, array $children): array
    {
        return [
            'blockName'    => $name,
            'attrs'        => $attrs,
            'innerBlocks'  => $children,
            'innerHTML'    => $innerHTML,
            'innerContent' => [$innerHTML],
        ];
    }

    protected function renderInnerBlocks(array $blocks): string
    {
        $html = '';
        foreach ($blocks as $b) $html .= ($b['innerHTML'] ?? '') . "\n";
        return $html;
    }

    // SEO 适配
    public function setSEOTitle(int $postId, string $title): bool
    {
        return false;
    }

    public function setSEODescription(int $postId, string $desc): bool
    {
        return false;
    }

    public function setSEOKeywords(int $postId, array $keywords): bool
    {
        return false;
    }

    // 内部

    protected function notSupported(string $feature): array
    {
        return [
            'success' => false,
            'message' => "当前主题不支持{$feature}",
            'code'    => 'theme_not_adapted',
        ];
    }
}
