<script setup lang="ts">
import { cherryInstance } from './components/CherryMarkdown';
import { invoke } from '@tauri-apps/api/core';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { open, save } from '@tauri-apps/plugin-dialog';
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
import { register, unregister } from '@tauri-apps/plugin-global-shortcut';
import { useFileStore } from './store';
import { ref, onMounted, onUnmounted } from 'vue';
import SidePanelManager from './components/SidePanelManager.vue';
import ToastContainer from './components/ui/ToastContainer.vue';
import UnsavedChangesDialog, { type UnsavedDialogResult } from './components/ui/UnsavedChangesDialog.vue';
import type { FileOperationResult } from './components/types';
import { useAppEvents, type OpenFileFromSidebarEvent } from './components/composables/useAppEvents';
import { notifyError, notifySuccess } from './utils/notifications';
import { MESSAGES, DIALOGS } from './constants/i18n';

// 响应式数据
let cherryMarkdown = cherryInstance();
const fileStore = useFileStore();
const appWindow = getCurrentWindow();
let needDealAfterChange = false;
let hasUnsavedChanges = false;
let unlistenCloseRequested: (() => void) | undefined;

// 加载状态(防止重复点击)
const isLoading = ref(false);

// 未保存对话框状态
const showUnsavedDialog = ref(false);
let unsavedDialogResolve: ((_result: UnsavedDialogResult) => void) | null = null;
const preventNativeContextMenu = (event: Event): void => {
  event.preventDefault();
};

// 暴露未保存更改的检查函数供外部使用
const checkUnsavedChanges = (): boolean => {
  return hasUnsavedChanges;
};

/**
 * 显示三选项未保存对话框
 * @returns 'save' | 'discard' | 'cancel'
 */
const showUnsavedConfirmDialog = (): Promise<UnsavedDialogResult> => {
  return new Promise((resolve) => {
    unsavedDialogResolve = resolve;
    showUnsavedDialog.value = true;
  });
};

const handleUnsavedDialogClose = (_result: UnsavedDialogResult): void => {
  showUnsavedDialog.value = false;
  if (unsavedDialogResolve) {
    unsavedDialogResolve(_result);
    unsavedDialogResolve = null;
  }
};

/**
 * 统一的未保存更改确认逻辑
 * @returns true 表示可以继续操作,false 表示取消
 */
const confirmProceedWhenUnsaved = async (): Promise<boolean> => {
  if (!hasUnsavedChanges) return true;

  const result = await showUnsavedConfirmDialog();

  if (result === 'save') {
    // 保存并继续:只执行保存,不继续后续操作(不销毁当前内容)
    await saveMarkdown();
    return false;
  }
  if (result === 'discard') {
    // 放弃更改,继续操作
    return true;
  }
  // 取消操作
  return false;
};

// ========== 窗口标题管理 ==========
const updateTitle = async (path: string | null, unsaved: boolean = false): Promise<void> => {
  let fileName = '';
  if (path) {
    // 从路径中提取文件名
    const pathParts = path.split(/[\\\\/]/);
    fileName = pathParts[pathParts.length - 1];
  }
  const unsavedIndicator = unsaved ? '● ' : '';
  const title = path ? `${unsavedIndicator}${fileName} - Cherry Markdown` : 'Cherry Markdown';
  await appWindow.setTitle(title);
};

// ========== 文件操作函数 ==========
const newFile = async (): Promise<void> => {
  if (!(await confirmProceedWhenUnsaved())) return;
  needDealAfterChange = false;
  hasUnsavedChanges = false;
  cherryMarkdown.setMarkdown('');
  fileStore.setCurrentFilePath('');
  await updateTitle(null, false);
};

const openFile = async (): Promise<FileOperationResult> => {
  if (isLoading.value) return { success: false, error: DIALOGS.CANCELLED_UNSAVED };
  if (!(await confirmProceedWhenUnsaved())) {
    return { success: false, error: DIALOGS.CANCELLED_UNSAVED };
  }

  isLoading.value = true;
  try {
    const path = await open({
      multiple: false,
      directory: false,
      filters: [
        {
          name: 'markdown',
          extensions: ['md', 'text'],
        },
      ],
    });

    if (path === null) {
      return { success: false, error: MESSAGES.FILE.USER_CANCELLED_SELECT };
    }

    const markdown = await readTextFile(path);
    needDealAfterChange = false;
    hasUnsavedChanges = false;
    cherryMarkdown.setMarkdown(markdown);
    fileStore.setCurrentFilePath(path);

    // 添加到最近访问列表
    fileStore.addRecentFile(path);
    await updateTitle(path, false);

    return { success: true, path };
  } catch (error) {
    const message = `${MESSAGES.FILE.OPEN_FAILED}: ${error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR}`;
    notifyError(message);
    return { success: false, error: error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR };
  } finally {
    isLoading.value = false;
  }
};

const saveAsNewMarkdown = async (): Promise<FileOperationResult> => {
  if (isLoading.value) return { success: false, error: MESSAGES.FILE.USER_CANCELLED };
  isLoading.value = true;
  try {
    const markdown = cherryMarkdown.getMarkdown();
    const path = await save({
      filters: [
        {
          name: 'Cherry Markdown',
          extensions: ['md', 'markdown'],
        },
      ],
    });

    if (!path) {
      return { success: false, error: MESSAGES.FILE.USER_CANCELLED_SAVE };
    }

    await writeTextFile(path, markdown);
    fileStore.setCurrentFilePath(path);
    fileStore.addRecentFile(path);
    fileStore.markSaved(path);
    hasUnsavedChanges = false;
    await updateTitle(path, false);
    notifySuccess(MESSAGES.FILE.SAVE_AS_SUCCESS);

    return { success: true, path };
  } catch (error) {
    const message = `${MESSAGES.FILE.SAVE_AS_FAILED}: ${error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR}`;
    notifyError(message);
    return { success: false, error: error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR };
  } finally {
    isLoading.value = false;
  }
};

const saveMarkdown = async (): Promise<FileOperationResult> => {
  try {
    const markdown = cherryMarkdown.getMarkdown();

    if (!fileStore.currentFilePath) {
      return await saveAsNewMarkdown();
    }

    await writeTextFile(fileStore.currentFilePath, markdown);
    fileStore.markSaved(fileStore.currentFilePath);
    hasUnsavedChanges = false;
    await updateTitle(fileStore.currentFilePath, false);
    notifySuccess(MESSAGES.FILE.SAVE_SUCCESS);
    return { success: true, path: fileStore.currentFilePath };
  } catch (error) {
    const message = `${MESSAGES.FILE.SAVE_FAILED}: ${error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR}`;
    notifyError(message);
    return { success: false, error: error instanceof Error ? error.message : MESSAGES.UNKNOWN_ERROR };
  }
};

// ========== 编辑器模式管理 ==========
const switchToPreviewOnly = (): void => {
  cherryMarkdown.wrapperDom.classList.add('markdown-preview-only');

  // 隐藏编辑按钮
  const pen = cherryMarkdown.wrapperDom.querySelector('.cherry-toolbar-pen');
  if (pen) {
    pen.classList.remove('active');
  }
  cherryMarkdown.previewer.options.enablePreviewerBubble = false;
};

const switchToEdit = (): void => {
  cherryMarkdown.wrapperDom.classList.remove('markdown-preview-only');
  // 显示编辑按钮
  const pen = cherryMarkdown.wrapperDom.querySelector('.cherry-toolbar-pen');
  if (pen) {
    pen.classList.add('active');
  }
  cherryMarkdown.previewer.options.enablePreviewerBubble = true;
};

const dealAfterChange = (): void => {
  if (!needDealAfterChange) {
    needDealAfterChange = true;
    return;
  }

  // 标记为有未保存的更改,不进行自动保存
  hasUnsavedChanges = true;
  if (fileStore.currentFilePath) {
    void updateTitle(fileStore.currentFilePath, true);
  }
};

const handleEditButtonClick = (): void => {
  const pen = cherryMarkdown.wrapperDom.querySelector('.cherry-toolbar-pen');

  if (pen) {
    if (cherryMarkdown.wrapperDom.classList.contains('markdown-preview-only')) {
      switchToEdit();
    } else {
      switchToPreviewOnly();
    }
  }
};

// ========== 文件恢复功能 ==========
const restoreLastOpenedFile = async (): Promise<void> => {
  if (fileStore.currentFilePath) {
    try {
      const markdown = await readTextFile(fileStore.currentFilePath);
      needDealAfterChange = false;
      hasUnsavedChanges = false;
      cherryMarkdown.setMarkdown(markdown);
      console.log('成功恢复上次打开的文件:', fileStore.currentFilePath);
      await updateTitle(fileStore.currentFilePath, false);
    } catch (error) {
      console.warn('恢复上次打开的文件失败:', error);
      // 如果文件不存在或无法访问,清除当前文件路径并从最近记录移除
      fileStore.removeRecentFile(fileStore.currentFilePath);
      fileStore.setCurrentFilePath(null);
      await updateTitle(null, false);
    }
  }
};

// ========== 事件处理函数 ==========
const handleOpenFileFromSidebar = async (event: OpenFileFromSidebarEvent): Promise<void> => {
  const { filePath, content } = event.detail;
  if (!(await confirmProceedWhenUnsaved())) return;
  needDealAfterChange = false;
  hasUnsavedChanges = false;
  cherryMarkdown.setMarkdown(content);
  fileStore.setCurrentFilePath(filePath);
  await updateTitle(filePath, false);
};

const handleSaveFromToolbar = async (): Promise<void> => {
  const result = await saveMarkdown();
  if (!result.success && result.error) {
    notifyError(`${MESSAGES.FILE.SAVE_FAILED}: ${result.error}`);
  }
};

// ========== 工具栏管理 ==========
const toggleToolbar = async (): Promise<void> => {
  const cherryNoToolbar = document.querySelector('.cherry--no-toolbar');
  await invoke('get_show_toolbar', { show: !!cherryNoToolbar });
  cherryMarkdown.toolbar.toolbarHandlers.settings('toggleToolbar');
};

// ========== 键盘快捷键处理 ==========
const registerSaveShortcut = async (): Promise<void> => {
  try {
    // 注册 Ctrl+S 保存快捷键
    await register('CommandOrControl+S', async () => {
      if (fileStore.currentFilePath || hasUnsavedChanges) {
        await saveMarkdown();
      }
    });
  } catch (error) {
    console.warn('注册保存快捷键失败:', error);
  }
};

const unregisterSaveShortcut = async (): Promise<void> => {
  try {
    await unregister('CommandOrControl+S');
  } catch (error) {
    console.warn('注销保存快捷键失败:', error);
  }
};

const appEvents = useAppEvents({
  onOpenFileFromSidebar: handleOpenFileFromSidebar,
  onRequestSave: handleSaveFromToolbar,
  tauriHandlers: {
    onNewFile: newFile,
    onOpenFile: openFile,
    onSave: saveMarkdown,
    onSaveAs: saveAsNewMarkdown,
    onToggleToolbar: toggleToolbar,
  },
});

// ========== 生命周期钩子 ==========
onMounted(async () => {
  // 暴露 checkUnsavedChanges 给 window,以便外部可以使用
  (window as any).checkUnsavedChanges = checkUnsavedChanges;

  // 禁用 Tauri 默认右键菜单(防止原生“查看页面元素”)
  document.addEventListener('contextmenu', preventNativeContextMenu);

  // 初始化工具栏状态
  const cherryNoToolbar = document.querySelector('.cherry--no-toolbar');
  await invoke('get_show_toolbar', { show: !cherryNoToolbar });
  cherryMarkdown = cherryInstance();
  appEvents.registerWindowEvents();
  await appEvents.registerTauriEvents();

  // 窗口关闭防护
  unlistenCloseRequested = await appWindow.onCloseRequested(async (event) => {
    const canClose = await confirmProceedWhenUnsaved();
    if (!canClose) {
      event.preventDefault();
    }
  });

  // 注册全局保存快捷键
  await registerSaveShortcut();

  // 设置编辑按钮事件监听
  setTimeout(() => {
    const pen = cherryMarkdown.wrapperDom.querySelector('.cherry-toolbar-pen');
    if (pen) {
      pen.removeEventListener('click', handleEditButtonClick);
      pen.addEventListener('click', handleEditButtonClick);
    }
  }, 100);

  // 自动恢复上次打开的文件
  await restoreLastOpenedFile();
  cherryMarkdown.on('afterChange', dealAfterChange);
});

onUnmounted(async () => {
  document.removeEventListener('contextmenu', preventNativeContextMenu);
  if (unlistenCloseRequested) {
    unlistenCloseRequested();
  }

  // 注销全局保存快捷键
  await unregisterSaveShortcut();
  await appEvents.cleanupAll();
});
</script>

<template>
  <div class="app-container">
    <SidePanelManager />
    <div class="editor-container">
      <div id="markdown-editor"></div>
    </div>
    <ToastContainer />
    <UnsavedChangesDialog :visible="showUnsavedDialog" @close="handleUnsavedDialogClose" />
  </div>
</template>

<style scoped>
.app-container {
  display: flex;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
}

.editor-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  position: relative;
}

#markdown-editor {
  height: 100%;
  width: 100%;
  flex: 1;
}
</style>