import { 
	App, 
	PluginSettingTab, 
	Setting,
	requireApiVersion,
 } from "obsidian";
import * as ObsidianModule from "obsidian";
import EasyCopy from "./main";
import { LinkFormat, BlockIdInsertPosition } from "./type";

interface SettingsContainer {
	addSetting(cb: (setting: Setting) => void): void;
}

function createSettingsGroup(containerEl: HTMLElement, heading?: string): SettingsContainer {
	// Check if SettingGroup is available (API 1.11.0+)
	// requireApiVersion is the official Obsidian API method for version checking
	if (requireApiVersion('1.11.0')) {
		// Use SettingGroup - it's guaranteed to exist if requireApiVersion returns true
		// Access SettingGroup via type assertion since it may not be in type definitions
		// for older TypeScript versions, but exists at runtime in Obsidian 1.11.0+
		// Using unknown instead of any to satisfy eslint while maintaining type safety
		const SettingGroupClass = (ObsidianModule as unknown as { SettingGroup?: new (containerEl: HTMLElement) => {
			setHeading(heading: string): {
				addSetting(cb: (setting: Setting) => void): void;
			};
			addSetting(cb: (setting: Setting) => void): void;
		} }).SettingGroup;
		
		if (SettingGroupClass) {
			const group = heading 
				? new SettingGroupClass(containerEl).setHeading(heading)
				: new SettingGroupClass(containerEl);
			return {
				addSetting(cb: (setting: Setting) => void) {
					group.addSetting(cb);
				}
			};
		}
	}
	
	// Fallback path (either API < 1.11.0 or SettingGroup not found)
	{
		// Fallback: Create a heading manually for older API versions
		// Note: While best practice prefers Setting.setHeading(), the fallback path
		// is for versions that may not support it, so manual heading is appropriate here
		if (heading) {
			const headingEl = containerEl.createDiv('setting-group-heading');
			headingEl.createEl('h3', { text: heading });
		}
		
		return {
			addSetting(cb: (setting: Setting) => void) {
				const setting = new Setting(containerEl);
				cb(setting);
			}
		};
	}
}


export class EasyCopySettingTab extends PluginSettingTab {
	plugin: EasyCopy;

	icon: string = 'copy-plus';

	constructor(app: App, plugin: EasyCopy) {
		super(app, plugin);
		this.plugin = plugin;
	}

	display(): void {
		const {containerEl} = this;

		containerEl.empty();

		const generalGroup = createSettingsGroup(containerEl);

		generalGroup.addSetting(setting => setting
			.setName(this.plugin.t('add-to-menu'))
			.setDesc(this.plugin.t('add-to-menu-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.addToMenu)
				.onChange(async (value) => {
				this.plugin.settings.addToMenu = value;
				await this.plugin.saveSettings();
			})));

		generalGroup.addSetting(setting => setting
			.setName(this.plugin.t('add-extra-commands'))
			.setDesc(this.plugin.t('add-extra-commands-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.addExtraCommands)
				.onChange(async (value) => {
				this.plugin.settings.addExtraCommands = value;
				await this.plugin.saveSettings();
			})));

		generalGroup.addSetting(setting => setting
			.setName(this.plugin.t('show-notice'))
			.setDesc(this.plugin.t('show-notice-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.showNotice)
				.onChange(async (value) => {
					this.plugin.settings.showNotice = value;
					await this.plugin.saveSettings();
				})));

		const formatGroup = createSettingsGroup(containerEl, this.plugin.t('format'));

		formatGroup.addSetting(setting => setting
			.setName(this.plugin.t('link-format'))
			.setDesc(this.plugin.t('link-format-desc'))
			.addDropdown(dropdown => dropdown
				.addOption(LinkFormat.OBSIDIAN, this.plugin.t('link-format-obsidian'))
				.addOption(LinkFormat.MDLINK, this.plugin.t('markdown-link'))
				.addOption(LinkFormat.WIKILINK, this.plugin.t('wiki-link'))
				.setValue(this.plugin.settings.linkFormat)
				.onChange(async (value) => {
					this.plugin.settings.linkFormat = value as LinkFormat;
					await this.plugin.saveSettings();
				})));

		formatGroup.addSetting(setting => setting
			.setName(this.plugin.t('use-heading-as-display'))
			.setDesc(this.plugin.t('use-heading-as-display-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.useHeadingAsDisplayText)
				.onChange(async (value) => {
					this.plugin.settings.useHeadingAsDisplayText = value;
					await this.plugin.saveSettings();
					this.display();
				})));

		// 新增：标题链接连接符设置，仅在禁用"使用标题作为显示文本"时显示
		if (!this.plugin.settings.useHeadingAsDisplayText) {
			formatGroup.addSetting(setting => setting
				.setName(this.plugin.t('heading-link-separator'))
				.setDesc(this.plugin.t('heading-link-separator-desc'))
				.addText(text => text
					.setPlaceholder('#')
					.setValue(this.plugin.settings.headingLinkSeparator)
					.onChange(async (value) => {
						this.plugin.settings.headingLinkSeparator = value || '#';
						await this.plugin.saveSettings();
					})
				));
		}

		// 后续新增：文件名包含标题时，简化为复制文件链接（通常用于复制一级标题时）
		formatGroup.addSetting(setting => setting
			.setName(this.plugin.t('simplified-heading-to-note-link'))
			.setDesc(this.plugin.t('simplified-heading-to-note-link-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.simplifiedHeadingToNoteLink)
				.onChange(async (value) => {
					this.plugin.settings.simplifiedHeadingToNoteLink = value;
					await this.plugin.saveSettings();
					this.display();
				})));

		if (this.plugin.settings.simplifiedHeadingToNoteLink) {
			formatGroup.addSetting(setting => setting
				.setName(this.plugin.t('strict-heading-match'))
				.setDesc(this.plugin.t('strict-heading-match-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.strictHeadingMatch)
					.onChange(async (value) => {
						this.plugin.settings.strictHeadingMatch = value;
						await this.plugin.saveSettings();
					})));
		}


		// 新增：是否使用 frontmatter 属性作为显示文本
		formatGroup.addSetting(setting => setting
			.setName(this.plugin.t('use-frontmatter-as-display'))
			.setDesc(this.plugin.t('use-frontmatter-as-display-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.useFrontmatterAsDisplay)
				.onChange(async (value) => {
					this.plugin.settings.useFrontmatterAsDisplay = value;
					await this.plugin.saveSettings();
					this.display();
				})
			));

		// 新增：自定义 frontmatter 属性名，仅在上方开启时显示
		if (this.plugin.settings.useFrontmatterAsDisplay) {
			formatGroup.addSetting(setting => setting
				.setName(this.plugin.t('frontmatter-key'))
				.setDesc(this.plugin.t('frontmatter-key-desc'))
				.addText(text => text
					.setPlaceholder('title')
					.setValue(this.plugin.settings.frontmatterKey)
					.onChange(async (value) => {
						this.plugin.settings.frontmatterKey = value || 'title';
						await this.plugin.saveSettings();
					})
				));
		}


		const blockIdGroup = createSettingsGroup(containerEl, this.plugin.t('block-id'));

		blockIdGroup.addSetting(setting => setting
			.setName(this.plugin.t('auto-add-block-id'))
			.setDesc(this.plugin.t('auto-add-block-id-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.autoAddBlockId)
				.onChange(async (value) => {
					this.plugin.settings.autoAddBlockId = value;
					await this.plugin.saveSettings();
					this.display();
				})));

		if (this.plugin.settings.autoAddBlockId) {
			// 新增：块ID插入位置设置
			blockIdGroup.addSetting(setting => setting
				.setName(this.plugin.t('block-id-insert-position'))
				.setDesc(this.plugin.t('block-id-insert-position-desc'))
				.addDropdown(dropdown => dropdown
					.addOption(BlockIdInsertPosition.END_OF_BLOCK, this.plugin.t('block-id-end-of-block'))
					.addOption(BlockIdInsertPosition.NEXT_LINE, this.plugin.t('block-id-next-line'))
					.setValue(this.plugin.settings.blockIdInsertPosition)
					.onChange(async (value) => {
						this.plugin.settings.blockIdInsertPosition = value as BlockIdInsertPosition;
						await this.plugin.saveSettings();
					})));
		}

		if (this.plugin.settings.autoAddBlockId) {
			blockIdGroup.addSetting(setting => setting
				.setName(this.plugin.t('manual-block-id'))
				.setDesc(this.plugin.t('manual-block-id-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.allowManualBlockId)
					.onChange(async (value) => {
						this.plugin.settings.allowManualBlockId = value;
						await this.plugin.saveSettings();
					})));
		}
		
		// 新增：自动为 Block 链接添加显示文本
		blockIdGroup.addSetting(setting => setting
			.setName(this.plugin.t('auto-block-display-text'))
			.setDesc(this.plugin.t('auto-block-display-text-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.autoBlockDisplayText)
				.onChange(async (value) => {
					this.plugin.settings.autoBlockDisplayText = value;
					await this.plugin.saveSettings();
					this.display();
				})
			));

		// 新增：块显示文本限制设置，仅在启用 autoBlockDisplayText 时显示
		if (this.plugin.settings.autoBlockDisplayText) {
			blockIdGroup.addSetting(setting => setting
				.setName(this.plugin.t('block-display-word-limit'))
				.setDesc(this.plugin.t('block-display-word-limit-desc'))
				.addText(text => text
					.setPlaceholder('3')
					.setValue(String(this.plugin.settings.blockDisplayWordLimit))
					.onChange(async (value) => {
						const numValue = parseInt(value) || 3;
						this.plugin.settings.blockDisplayWordLimit = Math.max(1, numValue);
						await this.plugin.saveSettings();
					})
				));

			blockIdGroup.addSetting(setting => setting
				.setName(this.plugin.t('block-display-char-limit'))
				.setDesc(this.plugin.t('block-display-char-limit-desc'))
				.addText(text => text
					.setPlaceholder('5')
					.setValue(String(this.plugin.settings.blockDisplayCharLimit))
					.onChange(async (value) => {
						const numValue = parseInt(value) || 5;
						this.plugin.settings.blockDisplayCharLimit = Math.max(1, numValue);
						await this.plugin.saveSettings();
					})
				));
		}

		const targetGroup = createSettingsGroup(containerEl, this.plugin.t('target'));

		targetGroup.addSetting(setting => setting
			.setName(this.plugin.t('customize-targets'))
			.setDesc(this.plugin.t('customize-targets-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.customizeTargets)
				.onChange(async (value) => {
					this.plugin.settings.customizeTargets = value;
					await this.plugin.saveSettings();
					this.display();
				})));

		// 只有当自定义复制对象选项开启时才显示具体的复制对象选项
		if (this.plugin.settings.customizeTargets) {
			targetGroup.addSetting(setting => setting
				.setName(this.plugin.t('enable-inline-code'))
				.setDesc(this.plugin.t('enable-inline-code-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.enableInlineCode)
					.onChange(async (value) => {
						this.plugin.settings.enableInlineCode = value;
						await this.plugin.saveSettings();
					})));

			targetGroup.addSetting(setting => setting
				.setName(this.plugin.t('enable-bold'))
				.setDesc(this.plugin.t('enable-bold-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.enableBold)
					.onChange(async (value) => {
						this.plugin.settings.enableBold = value;
						await this.plugin.saveSettings();
					})));

			targetGroup.addSetting(setting => setting
				.setName(this.plugin.t('enable-highlight'))
				.setDesc(this.plugin.t('enable-highlight-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.enableHighlight)
					.onChange(async (value) => {
						this.plugin.settings.enableHighlight = value;
						await this.plugin.saveSettings();
					})));

			targetGroup.addSetting(setting => setting
				.setName(this.plugin.t('enable-italic'))
				.setDesc(this.plugin.t('enable-italic-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.enableItalic)
					.onChange(async (value) => {
						this.plugin.settings.enableItalic = value;
						await this.plugin.saveSettings();
					})));
            
            targetGroup.addSetting(setting => setting
                .setName(this.plugin.t('enable-strikethrough'))
                .setDesc(this.plugin.t('enable-strikethrough-desc'))
                .addToggle(toggle => toggle
                    .setValue(this.plugin.settings.enableStrikethrough)
                    .onChange(async (value) => {
                        this.plugin.settings.enableStrikethrough = value;
                        await this.plugin.saveSettings();
                    })));
            
            targetGroup.addSetting(setting => setting
                .setName(this.plugin.t('enable-inline-latex'))
                .setDesc(this.plugin.t('enable-inline-latex-desc'))
                .addToggle(toggle => toggle
                    .setValue(this.plugin.settings.enableInlineLatex)
                    .onChange(async (value) => {
                        this.plugin.settings.enableInlineLatex = value;
                        await this.plugin.saveSettings();
                    })));
            
            targetGroup.addSetting(setting => setting
                .setName(this.plugin.t('enable-link'))
                .setDesc(this.plugin.t('enable-link-desc'))
                .addToggle(toggle => toggle
                    .setValue(this.plugin.settings.enableLink)
                    .onChange(async (value) => {
                        this.plugin.settings.enableLink = value;
                        await this.plugin.saveSettings();
                    })));

            targetGroup.addSetting(setting => setting
                .setName(this.plugin.t('enable-wikilink'))
                .setDesc(this.plugin.t('enable-wikilink-desc'))
                .addToggle(toggle => toggle
                    .setValue(this.plugin.settings.enableWikiLink ?? true)
                    .onChange(async (value) => {
                        this.plugin.settings.enableWikiLink = value;
                        await this.plugin.saveSettings();
						this.display(); // 切换后刷新界面以显示/隐藏下方选项
                    })));
            
		}

		targetGroup.addSetting(setting => setting
			.setName(this.plugin.t('enable-callout-copy'))
			.setDesc(this.plugin.t('enable-callout-copy-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.enableCalloutCopy ?? true)
				.onChange(async (value) => {
					this.plugin.settings.enableCalloutCopy = value;
					await this.plugin.saveSettings();
					this.display();
				})));
		// 优先复制 Callout 内容
		if (this.plugin.settings.enableCalloutCopy) {
			targetGroup.addSetting(setting => setting
				.setName(this.plugin.t('callout-copy-priority'))
				.setDesc(this.plugin.t('callout-copy-priority-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.calloutCopyPriority ?? true)
					.onChange(async (value) => {
						this.plugin.settings.calloutCopyPriority = value;
						await this.plugin.saveSettings();
					})));
		}

		
		const specialFormatGroup = createSettingsGroup(containerEl, this.plugin.t('special-format'));
				
		// 块链接特殊格式选项
		specialFormatGroup.addSetting(setting => setting
			.setName(this.plugin.t('auto-embed-block-link'))
			.setDesc(this.plugin.t('auto-embed-block-link-desc'))
			.addToggle(toggle => toggle
				.setValue(this.plugin.settings.autoEmbedBlockLink ?? false)
				.onChange(async (value) => {
					this.plugin.settings.autoEmbedBlockLink = value;
					await this.plugin.saveSettings();
				})));

		// 仅当启用 Wiki 链接复制时显示
		if (this.plugin.settings.enableWikiLink) {
			specialFormatGroup.addSetting(setting => setting
				.setName(this.plugin.t('keep-wiki-brackets'))
				.setDesc(this.plugin.t('keep-wiki-brackets-desc'))
				.addToggle(toggle => toggle
					.setValue(this.plugin.settings.keepWikiBrackets ?? true)
					.onChange(async (value) => {
						this.plugin.settings.keepWikiBrackets = value;
						await this.plugin.saveSettings();
					})));
		}
	}
}
