import { IBimComponent } from '../../types/component';
import { localeManager, t } from '../../services/locale';
import { themeManager } from '../../services/theme';
import type { ThemeConfig } from '../../themes/types';
import type { TabItem, TabOptions } from './index.type';
import './index.css';

/**
 * 简单标签页组件（固定标签，不支持运行时增删）
 * - 仅处理标签头部与内容切换
 * - 主题从 ThemeManager 获取，不在配置中传入
 * - 文案通过 t() 翻译，支持传原文直接展示
 */
export class BimTab implements IBimComponent {
    /** 组件根节点 */
    public element: HTMLElement;
    /** 头部容器 */
    private navElement: HTMLElement;
    /** 内容容器 */
    private contentElement: HTMLElement;
    /** 业务配置 */
    private options: TabOptions;
    /** 当前激活的标签 id */
    private activeId: string | null;
    /** id -> TabItem */
    private tabMap: Map<string, TabItem> = new Map();
    /** id -> 内容容器 */
    private panelMap: Map<string, HTMLElement> = new Map();
    /** 主题/语言订阅解除函数 */
    private unsubscribeLocale: (() => void) | null = null;
    private unsubscribeTheme: (() => void) | null = null;
    /** 头部点击事件处理引用（便于销毁时解绑） */
    private navClickHandler: ((e: MouseEvent) => void) | null = null;

    constructor(options: TabOptions) {
        this.options = options;
        this.activeId = options.activeId || (options.tabs[0]?.id ?? null);

        // 预置 tabMap，方便后续查找
        options.tabs.forEach((tab) => this.tabMap.set(tab.id, tab));

        // 构建基础 DOM 结构
        this.element = document.createElement('div');
        this.element.className = 'bim-tab';

        this.navElement = document.createElement('div');
        this.navElement.className = 'bim-tab__nav';
        this.navElement.setAttribute('role', 'tablist');
        this.element.appendChild(this.navElement);

        this.contentElement = document.createElement('div');
        this.contentElement.className = 'bim-tab__content';
        this.element.appendChild(this.contentElement);

        // 挂载到容器
        this.options.container.appendChild(this.element);
    }

    /**
     * 初始化组件
     */
    public init(): void {
        this.renderNav();
        this.renderPanels();
        // 初始化文案与主题
        this.setLocales();
        this.setTheme(themeManager.getTheme());

        // 订阅语言、主题变化
        this.unsubscribeLocale = localeManager.subscribe(() => this.setLocales());
        this.unsubscribeTheme = themeManager.subscribe((theme) => this.setTheme(theme));
    }

    /**
     * 渲染头部标签
     */
    private renderNav(): void {
        this.navElement.innerHTML = '';

        this.navClickHandler = (event: MouseEvent) => {
            const target = (event.target as HTMLElement).closest<HTMLButtonElement>('.bim-tab__item');
            if (!target) return;
            const tabId = target.dataset.id;
            if (!tabId) return;
            const tab = this.tabMap.get(tabId);
            if (tab?.disabled) return;
            this.activateTab(tabId);
        };
        this.navElement.addEventListener('click', this.navClickHandler);

        this.options.tabs.forEach((tab) => {
            const btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'bim-tab__item';
            btn.dataset.id = tab.id;
            btn.setAttribute('role', 'tab');
            btn.id = `tab-${tab.id}`;
            btn.setAttribute('aria-selected', `${tab.id === this.activeId}`);
            if (tab.disabled) {
                btn.disabled = true;
                btn.setAttribute('aria-disabled', 'true');
                btn.classList.add('is-disabled');
            }

            // 图标
            if (tab.icon) {
                const iconEl = document.createElement('span');
                iconEl.className = 'bim-tab__icon';
                iconEl.innerHTML = tab.icon;
                btn.appendChild(iconEl);
            }

            const titleEl = document.createElement('span');
            titleEl.className = 'bim-tab__title';
            titleEl.textContent = this.resolveTitle(tab.title);
            btn.appendChild(titleEl);

            if (tab.id === this.activeId) {
                btn.classList.add('is-active');
            }

            this.navElement.appendChild(btn);
        });
    }

    /**
     * 渲染内容面板
     */
    private renderPanels(): void {
        this.contentElement.innerHTML = '';
        this.panelMap.clear();

        this.options.tabs.forEach((tab) => {
            const panel = document.createElement('div');
            panel.className = 'bim-tab__panel';
            panel.dataset.id = tab.id;
            panel.setAttribute('role', 'tabpanel');
            panel.setAttribute('aria-labelledby', `tab-${tab.id}`);

            if (tab.content instanceof HTMLElement) {
                panel.appendChild(tab.content);
            } else if (typeof tab.content === 'string') {
                panel.innerHTML = tab.content;
            }

            if (tab.id === this.activeId) {
                panel.classList.add('is-active');
            } else {
                panel.style.display = 'none';
            }

            this.panelMap.set(tab.id, panel);
            this.contentElement.appendChild(panel);
        });
    }

    /**
     * 激活指定标签
     * @param tabId 目标标签 id
     */
    public activateTab(tabId: string): void {
        if (this.activeId === tabId) return;
        const targetTab = this.tabMap.get(tabId);
        if (!targetTab || targetTab.disabled) return;

        this.activeId = tabId;
        // 更新头部状态
        const buttons = this.navElement.querySelectorAll<HTMLButtonElement>('.bim-tab__item');
        buttons.forEach((btn) => {
            const isActive = btn.dataset.id === tabId;
            btn.classList.toggle('is-active', isActive);
            btn.setAttribute('aria-selected', `${isActive}`);
        });

        // 更新面板显示
        this.panelMap.forEach((panel, id) => {
            const isActive = id === tabId;
            panel.classList.toggle('is-active', isActive);
            panel.style.display = isActive ? 'block' : 'none';
        });

        if (this.options.onChange) {
            this.options.onChange(tabId, targetTab);
        }
    }

    /**
     * 应用主题
     */
    public setTheme(theme: ThemeConfig): void {
        const style = this.element.style;
        style.setProperty('--bim-tab-bg', theme.panelBackground);
        style.setProperty('--bim-tab-nav-bg', theme.panelBackground);
        style.setProperty('--bim-tab-text', theme.textPrimary);
        style.setProperty('--bim-tab-text-secondary', theme.textSecondary);
        style.setProperty('--bim-tab-text-active', theme.primary);
        style.setProperty('--bim-tab-border', theme.border);
        style.setProperty('--bim-tab-hover-bg', theme.componentHover);
        style.setProperty('--bim-tab-active-bg', theme.componentActive);
        style.setProperty('--bim-tab-icon', theme.icon);
    }

    /**
     * 应用当前语言文案
     */
    public setLocales(): void {
        const buttons = this.navElement.querySelectorAll<HTMLButtonElement>('.bim-tab__item');
        buttons.forEach((btn) => {
            const id = btn.dataset.id;
            if (!id) return;
            const tab = this.tabMap.get(id);
            if (!tab) return;
            const titleEl = btn.querySelector<HTMLElement>('.bim-tab__title');
            if (titleEl) {
                titleEl.textContent = this.resolveTitle(tab.title);
            }
        });
    }

    /**
     * 清理资源
     */
    public destroy(): void {
        if (this.navClickHandler) {
            this.navElement.removeEventListener('click', this.navClickHandler);
            this.navClickHandler = null;
        }
        if (this.unsubscribeLocale) {
            this.unsubscribeLocale();
            this.unsubscribeLocale = null;
        }
        if (this.unsubscribeTheme) {
            this.unsubscribeTheme();
            this.unsubscribeTheme = null;
        }
        this.panelMap.clear();
        this.tabMap.clear();
        this.element.remove();
    }

    /**
     * 工具：解析标题（优先翻译，不存在则回退原值）
     */
    private resolveTitle(title: string): string {
        try {
            const translated = t(title);
            return translated || title;
        } catch (err) {
            // 翻译失败时使用原值
            return title;
        }
    }
}

