<script setup lang="ts">
import { ref, watch, onMounted, computed, onUnmounted, nextTick } from "vue";
import { open } from "@tauri-apps/plugin-dialog";
import { invoke } from "@tauri-apps/api/core";
import { ElMessage } from 'element-plus';
import { Document, VideoPlay, CircleCheck, Moon, Sunny, Delete, UploadFilled, Refresh } from '@element-plus/icons-vue';
import { listen, UnlistenFn } from '@tauri-apps/api/event';

// Navigation
const activeMenu = ref("preparation");

// Theme
const isDark = ref(false);

const toggleTheme = (val: string | number | boolean) => {
  const isDarkMode = val === true;
  isDark.value = isDarkMode;
  if (isDarkMode) {
    document.documentElement.classList.add('dark');
    localStorage.setItem('theme', 'dark');
  } else {
    document.documentElement.classList.remove('dark');
    localStorage.setItem('theme', 'light');
  }
};

// Data
const workingDir = ref("");
const templateDir = ref("");
const selectedDate = ref<Date | null>(new Date());
const currentDir = ref("");
const videoNamePrefix = ref("");
const isCurrentDirValid = ref(false);

// Review Data
const importedFiles = ref<string[]>([]);
const videoNameInput = ref("");
const historyList = ref<string[]>([]);
const historyMap = ref<Record<string, string[]>>({});
const currentHistoryKey = ref(""); 

// Check Data
const checkLogs = ref<string[]>([]);
const logContainerRef = ref<HTMLElement | null>(null);
const checkPageScrollTop = ref(0);

// Lifecycle
let unlistenDrop: UnlistenFn | null = null;

const handleLogScroll = (e: Event) => {
    const target = e.target as HTMLElement;
    checkPageScrollTop.value = target.scrollTop;
}

watch(activeMenu, async (newVal) => {
  if (newVal === 'check') {
    await nextTick();
    if (logContainerRef.value) {
      logContainerRef.value.scrollTop = checkPageScrollTop.value;
    }
  }
});

onMounted(async () => {
  // Theme init
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
    isDark.value = true;
    document.documentElement.classList.add('dark');
  } else {
    isDark.value = false;
    document.documentElement.classList.remove('dark');
  }
  
  // Config init
  await loadConfig();
  
  // Validate initial dir
  validateCurrentDir();

  // Load History
  loadHistory();

  // Listen for file drops
  unlistenDrop = await listen<{ paths: string[] }>('tauri://drag-drop', (event) => {
    if (activeMenu.value === 'review' && !isReviewDisabled.value) {
      handleFileDrop(event.payload.paths);
    }
  });
});

onUnmounted(() => {
  if (unlistenDrop) {
    unlistenDrop();
  }
});

// Config & Validation
interface AppConfig {
    working_dir: string;
    template_dir: string;
}

const loadConfig = async () => {
    try {
        const config = await invoke<AppConfig>('load_config');
        if (config.working_dir) workingDir.value = config.working_dir;
        if (config.template_dir) templateDir.value = config.template_dir;
    } catch (e) {
        console.error("Failed to load config:", e);
    }
}

const saveConfig = async () => {
    try {
        await invoke('save_config', {
            config: {
                working_dir: workingDir.value,
                template_dir: templateDir.value
            }
        });
    } catch (e) {
        console.error("Failed to save config:", e);
    }
}

const validateCurrentDir = async () => {
    if (!currentDir.value) {
        isCurrentDirValid.value = false;
        return;
    }
    try {
        const exists = await invoke<boolean>('check_dir_exists', { path: currentDir.value });
        isCurrentDirValid.value = exists;
    } catch (e) {
        isCurrentDirValid.value = false;
    }
}

watch([workingDir, templateDir], saveConfig);
watch(currentDir, validateCurrentDir);

// History Logic
const loadHistory = async () => {
  try {
     const history = await invoke<Record<string, string[]>>('load_history');
     historyMap.value = history || {};
  } catch (e) {
    console.error("Failed to load history", e);
  }
}

const updateHistoryList = () => {
    if (!currentHistoryKey.value) {
        historyList.value = [];
        return;
    }
    historyList.value = historyMap.value[currentHistoryKey.value] || [];
}

const handleFileDrop = (paths: string[]) => {
    importedFiles.value = paths;
    
    if (paths.length > 0 && currentDir.value) {
        const firstFile = paths[0];
        const separator = firstFile.includes('\\') ? '\\' : '/';
        const lastSeparatorIndex = firstFile.lastIndexOf(separator);
        const parentDir = firstFile.substring(0, lastSeparatorIndex);
        
        if (parentDir.startsWith(currentDir.value)) {
            let relative = parentDir.substring(currentDir.value.length);
            if (relative.startsWith(separator)) {
                relative = relative.substring(1);
            }
            currentHistoryKey.value = relative;
        } else {
             currentHistoryKey.value = ""; 
        }
        updateHistoryList();
    }
}

const deleteHistoryItem = async (val: string) => {
    if (!currentHistoryKey.value) return;
    try {
        const newMap = await invoke<Record<string, string[]>>('remove_history_item', {
            key: currentHistoryKey.value,
            value: val
        });
        historyMap.value = newMap;
        updateHistoryList();
    } catch (e) {
        ElMessage.error("删除失败: " + e);
    }
}

const handleRename = async () => {
    if (!videoNameInput.value) {
        ElMessage.warning("请输入名称");
        return;
    }
    if (importedFiles.value.length === 0) {
        ElMessage.warning("请先拖入视频文件");
        return;
    }
    
    if (currentHistoryKey.value) {
        try {
             const newMap = await invoke<Record<string, string[]>>('save_history_item', {
                key: currentHistoryKey.value,
                value: videoNameInput.value
            });
            historyMap.value = newMap;
            updateHistoryList();
        } catch (e) {
            console.error("History save failed", e);
        }
    }

    try {
        const msg = await invoke<string>('rename_videos', {
            files: importedFiles.value,
            prefix: videoNamePrefix.value,
            baseName: videoNameInput.value
        });
        ElMessage.success(msg);
        importedFiles.value = [];
    } catch (e) {
        ElMessage.error("重命名失败: " + e);
    }
}

const useHistoryItem = (val: string) => {
    videoNameInput.value = val;
}

// Check Logic
const appendLog = (msg: string) => {
    checkLogs.value.push(msg);
    nextTick(() => {
        if (logContainerRef.value) {
            logContainerRef.value.scrollTop = logContainerRef.value.scrollHeight;
        }
    });
}

const appendLogs = (msgs: string[]) => {
    checkLogs.value.push(...msgs);
     nextTick(() => {
        if (logContainerRef.value) {
            logContainerRef.value.scrollTop = logContainerRef.value.scrollHeight;
        }
    });
}

const handleDeleteEmptyDirs = async () => {
    appendLog("\n" + "=".repeat(20));
    appendLog("正在扫描并删除空目录...");
    try {
        const deleted = await invoke<string[]>('delete_empty_dirs', { path: currentDir.value });
        if (deleted.length === 0) {
            appendLog("未发现空目录。");
        } else {
            const batchSize = 100;
            for (let i = 0; i < deleted.length; i += batchSize) {
                const batch = deleted.slice(i, i + batchSize).map(p => `已删除: ${p}`);
                appendLogs(batch);
                await new Promise(resolve => setTimeout(resolve, 50)); // Small delay for rendering
            }
            appendLog(`删除完毕，共删除 ${deleted.length} 个空目录。`);
        }
    } catch (e) {
        appendLog(`错误: ${e}`);
    }
}

const handleCheckNaming = async () => {
    appendLog("\n" + "=".repeat(20));
    appendLog(`正在检查文件命名，前缀要求: ${videoNamePrefix.value} ...`);
    try {
        const mismatches = await invoke<string[]>('check_file_naming', { 
            path: currentDir.value, 
            prefix: videoNamePrefix.value 
        });
        
        if (mismatches.length === 0) {
            appendLog("检查完毕，所有文件均符合命名规范。");
        } else {
            appendLog(`发现 ${mismatches.length} 个文件不符合规范:`);
            mismatches.sort();
            
            // Format logs first
            const formattedLogs = mismatches.map(path => {
                let displayPath = path;
                if (path.startsWith(currentDir.value)) {
                    displayPath = "." + path.substring(currentDir.value.length);
                }
                return displayPath;
            });

             const batchSize = 100;
             for (let i = 0; i < formattedLogs.length; i += batchSize) {
                 const batch = formattedLogs.slice(i, i + batchSize);
                 appendLogs(batch);
                 await new Promise(resolve => setTimeout(resolve, 50)); 
             }
        }
    } catch (e) {
        appendLog(`错误: ${e}`);
    }
}

// Computed
const isReviewDisabled = computed(() => {
    return !isCurrentDirValid.value || !videoNamePrefix.value;
});

const reviewWarningMessage = computed(() => {
    if (!currentDir.value) return "请先设置当前目录";
    if (!isCurrentDirValid.value) return "当前目录不存在，请检查";
    if (!videoNamePrefix.value) return "文件前缀为空";
    return "";
});


// Actions (Preparation)
const selectWorkingDir = async () => {
  const selected = await open({
    directory: true,
    multiple: false,
  });
  if (selected) {
    workingDir.value = selected as string;
  }
};

const selectTemplateDir = async () => {
  const selected = await open({
    directory: true,
    multiple: false,
  });
  if (selected) {
    templateDir.value = selected as string;
  }
};

const selectCurrentDir = async () => {
  const selected = await open({
    directory: true,
    multiple: false,
  });
  if (selected) {
    currentDir.value = selected as string;
  }
};

const handleCopy = async () => {
  if (!workingDir.value || !templateDir.value || !selectedDate.value) {
    ElMessage.error("请填写完整信息（工作目录、模板目录、日期）");
    return;
  }

  const date = selectedDate.value;
  const mm = String(date.getMonth() + 1).padStart(2, '0');
  const dd = String(date.getDate()).padStart(2, '0');
  const folderName = `${mm}${dd}视频`;

  try {
    const newPath = await invoke<string>("copy_directory", {
      templatePath: templateDir.value,
      targetPath: workingDir.value,
      newFolderName: folderName,
    });
    
    ElMessage.success("目录拷贝并重命名成功！");
    currentDir.value = newPath;
  } catch (error) {
    ElMessage.error(`错误: ${error}`);
  }
};

// Reactivity for Current Directory Prefix
watch(currentDir, (newPath) => {
  if (!newPath) return;
  const dirName = newPath.split(/[\/\\]/).pop();
  if (!dirName) return;

  const regex = /^(\d{2})(\d{2})视频$/; 
  const match = dirName.match(regex);

  if (match) {
    const mm = match[1];
    const dd = match[2];
    const year = new Date().getFullYear();
    videoNamePrefix.value = `AI-${year}${mm}${dd}-`;
  }
});

</script>

<template>
  <el-container class="layout-container" style="height: 100vh">
    <el-aside width="200px" class="main-aside">
      <el-menu
        :default-active="activeMenu"
        class="el-menu-vertical-demo"
        @select="(index: string) => activeMenu = index"
        style="border-right: none; flex: 1;"
      >
        <el-menu-item index="preparation">
          <el-icon><Document /></el-icon>
          <span>准备</span>
        </el-menu-item>
        <el-menu-item index="review">
          <el-icon><VideoPlay /></el-icon>
          <span>审核</span>
        </el-menu-item>
        <el-menu-item index="check">
          <el-icon><CircleCheck /></el-icon>
          <span>检查</span>
        </el-menu-item>
      </el-menu>
      
      <div class="aside-footer">
         <el-switch
            v-model="isDark"
            inline-prompt
            :active-icon="Moon"
            :inactive-icon="Sunny"
            @change="toggleTheme"
          />
      </div>
    </el-aside>

    <el-main>
      <!-- Preparation Page -->
      <div v-if="activeMenu === 'preparation'">
        <h2>准备工作</h2>
        
        <el-card class="box-card" shadow="hover">
          <template #header>
            <div class="card-header">
              <span>新建任务</span>
            </div>
          </template>
          
          <el-form label-position="top">
            <el-form-item label="工作目录">
              <el-input v-model="workingDir" placeholder="请选择工作目录" readonly>
                <template #append>
                  <el-button @click="selectWorkingDir">选择</el-button>
                </template>
              </el-input>
            </el-form-item>
            
            <el-form-item label="分类模板">
              <el-input v-model="templateDir" placeholder="请选择分类模板" readonly>
                <template #append>
                  <el-button @click="selectTemplateDir">选择</el-button>
                </template>
              </el-input>
            </el-form-item>

            <el-form-item label="日期">
               <el-date-picker
                v-model="selectedDate"
                type="date"
                placeholder="选择日期"
                format="YYYY-MM-DD"
                style="width: 100%"
              />
            </el-form-item>

            <el-form-item>
              <el-button type="primary" @click="handleCopy" style="width: 100%">拷贝并重命名</el-button>
            </el-form-item>
          </el-form>
        </el-card>

        <!-- <el-divider /> -->

        <el-card class="box-card" shadow="hover">
           <template #header>
            <div class="card-header">
              <span>当前任务</span>
            </div>
          </template>

          <el-form label-position="top">
             <el-form-item label="当前目录">
              <el-input v-model="currentDir" placeholder="请选择或生成目录" readonly>
                 <template #append>
                  <el-button @click="selectCurrentDir">选择</el-button>
                </template>
              </el-input>
            </el-form-item>

            <el-form-item label="文件前缀">
              <el-input v-model="videoNamePrefix" placeholder="AI-yyyymmdd-" />
            </el-form-item>
          </el-form>
        </el-card>

      </div>

      <!-- Review Page -->
      <div v-else-if="activeMenu === 'review'">
        <h2>审核</h2>
        
        <el-alert
            v-if="isReviewDisabled"
            :title="reviewWarningMessage"
            type="warning"
            show-icon
            :closable="false"
            style="margin-bottom: 20px"
        />

        <div :class="{ 'disabled-area': isReviewDisabled }">
            <!-- Drag Area -->
            <div class="drag-area">
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">
                    将视频文件拖拽到此处
                </div>
                <div class="file-count-container">
                    <div class="file-count" v-show="importedFiles.length > 0">
                        已导入 {{ importedFiles.length }} 个文件
                    </div>
                </div>
            </div>

            <!-- Action Area -->
            <div class="action-area">
                 <el-input v-model="videoNameInput" placeholder="输入视频名称 (例如: 文本)" class="name-input">
                    <template #prepend>{{ videoNamePrefix }}</template>
                 </el-input>
                 <el-button type="primary" @click="handleRename" :disabled="isReviewDisabled || importedFiles.length === 0">命名</el-button>
            </div>
            
            <!-- History List -->
            <div class="history-area" v-if="historyList.length > 0">
                 <h4>历史记录 ({{ currentHistoryKey || '未关联目录' }})</h4>
                 <el-scrollbar max-height="300px">
                    <ul class="history-list">
                        <li v-for="item in historyList" :key="item" @click="useHistoryItem(item)">
                            <span class="history-text">{{ item }}</span>
                            <el-icon class="delete-icon" @click.stop="deleteHistoryItem(item)"><Delete /></el-icon>
                        </li>
                    </ul>
                 </el-scrollbar>
            </div>
             <div v-else-if="currentHistoryKey" class="no-history">
                <span class="text-secondary">该目录下暂无历史记录</span>
            </div>

        </div>
      </div>

      <!-- Check Page -->
      <div v-else-if="activeMenu === 'check'" style="display: flex; flex-direction: column; height: 100%; overflow: hidden;">
        <h2>检查</h2>

        <el-alert
            v-if="isReviewDisabled"
            :title="reviewWarningMessage"
            type="warning"
            show-icon
            :closable="false"
            style="margin-bottom: 20px"
        />

        <div :class="{ 'disabled-area': isReviewDisabled }" style="display: flex; flex-direction: column; flex-grow: 1; overflow: hidden;">
            <div class="check-actions">
                <el-button type="danger" :icon="Delete" @click="handleDeleteEmptyDirs">删除空目录</el-button>
                <el-button type="primary" :icon="Refresh" @click="handleCheckNaming">检查命名</el-button>
            </div>

            <div class="log-container">
                <div class="log-header">日志输出</div>
                <div class="log-content" ref="logContainerRef" @scroll="handleLogScroll">
                    <div v-for="(log, index) in checkLogs" :key="index" class="log-item">
                        {{ log }}
                    </div>
                    <div v-if="checkLogs.length === 0" class="log-empty">
                        暂无日志
                    </div>
                </div>
            </div>
        </div>
      </div>

    </el-main>
  </el-container>
</template>

<style>
body {
  margin: 0;
  font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
  background-color: var(--el-bg-color-page);
  color: var(--el-text-color-primary);
  transition: background-color 0.3s, color 0.3s;
}
.layout-container {
    height: 100vh;
}
.main-aside {
  background-color: var(--el-bg-color);
  border-right: 1px solid var(--el-border-color);
  display: flex;
  flex-direction: column;
  transition: background-color 0.3s, border-color 0.3s;
}
.aside-footer {
  padding: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-top: 1px solid var(--el-border-color);
}
.box-card {
  /* max-width: 800px; */
  margin-bottom: 20px;
}
/* Review Page Styles */
.disabled-area {
    opacity: 0.5;
    pointer-events: none;
}
.drag-area {
    border: 2px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: default;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
    padding: 20px 0;
    text-align: center;
    background-color: var(--el-bg-color-overlay);
    margin-bottom: 20px;
}
.el-icon--upload {
    font-size: 48px;
    color: var(--el-text-color-placeholder);
    margin-bottom: 10px;
    line-height: 1;
}
.el-upload__text {
    color: var(--el-text-color-regular);
    font-size: 14px;
    text-align: center;
}
.file-count-container {
    min-height: 24px; /* Adjust height as needed to fit the text */
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 10px; /* Add some space from the text above */
}
.file-count {
    /* margin-top: 10px; /* Removed, container handles spacing */
    color: var(--el-color-primary);
    font-weight: bold;
}
.action-area {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}
.history-area h4 {
    margin-bottom: 10px;
    color: var(--el-text-color-primary);
}
.history-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border: 1px solid var(--el-border-color);
    border-radius: 4px;
}
.history-list li {
    padding: 10px 15px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    border-bottom: 1px solid var(--el-border-color-lighter);
    background-color: var(--el-bg-color);
}
.history-list li:last-child {
    border-bottom: none;
}
.history-list li:hover {
    background-color: var(--el-fill-color-light);
}
.history-text {
    flex: 1;
}
.delete-icon {
    color: var(--el-text-color-secondary);
    transition: color 0.2s;
}
.delete-icon:hover {
    color: var(--el-color-danger);
}
.no-history {
    padding: 20px;
    text-align: center;
    color: var(--el-text-color-secondary);
}

/* Check Page Styles */
.check-actions {
    margin-bottom: 20px;
    display: flex;
    gap: 10px;
}
.log-container {
    border: 1px solid var(--el-border-color);
    border-radius: 4px;
    background-color: var(--el-bg-color);
    display: flex;
    flex-direction: column;
    flex-grow: 1; /* Make it fill available height */
    overflow: hidden; /* Prevent container from expanding beyond parent */
}
.log-header {
    padding: 10px 15px;
    background-color: var(--el-fill-color-light);
    border-bottom: 1px solid var(--el-border-color);
    font-weight: bold;
    font-size: 14px;
}
.log-content {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
    font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; /* Matched body font */
    font-size: 13px;
    white-space: pre-wrap;
}
.log-item {
    margin-bottom: 4px;
    line-height: 1.4;
}
.log-empty {
    color: var(--el-text-color-secondary);
    font-style: italic;
    text-align: center;
    margin-top: 20px;
}
</style>
