<template>
  <view class="common-phrases-page">
    <view class="tabs-bar">
      <view
        class="tab-item"
        :class="{ active: activeTab === 'mine' }"
        @click="switchTab('mine')"
      >
        我的常用语
      </view>
      <view
        class="tab-item"
        :class="{ active: activeTab === 'more' }"
        @click="switchTab('more')"
      >
        更多常用语
      </view>
    </view>

    <view class="content-wrapper">
      <view class="category-sidebar">
        <scroll-view class="category-list" scroll-y>
          <view
            v-for="category in currentCategories"
            :key="category.id"
            class="category-item"
            :class="{ active: currentCategory === category.id }"
            @click="handleCategoryClick(category)"
            @longpress="handleCategoryLongPress(category)"
          >
            <view class="category-content">
              <text class="category-name">{{ category.name }}</text>
              <view
                v-if="activeTab === 'mine' && isEditMode && category.deletable"
                class="delete-badge"
                @click.stop="deleteCategory(category)"
              >
                <uni-icons class="delete-icon" type="closeempty" size="12" color="#fff" />
              </view>
            </view>
          </view>
        </scroll-view>

        <view
          v-if="activeTab === 'mine'"
          class="add-category-footer"
          @click="showAddCategoryDialog"
        >
          <text class="add-category-text">新增分类</text>
        </view>
      </view>

      <view class="phrases-container">
        <view class="list-header">
          <view class="current-title">
            {{ currentCategoryName }}（{{ currentPhrases.length }}）
          </view>
          <view class="search-box">
            <uni-icons class="search-icon" type="search" size="16" color="#98a2b3" />
            <input
              v-model="searchKeyword"
              class="search-input"
              placeholder="搜索常用语"
              confirm-type="search"
            />
            <uni-icons
              v-if="searchKeyword"
              class="clear-search"
              type="closeempty"
              size="18"
              color="#98a2b3"
              @click="searchKeyword = ''"
            />
          </view>
        </view>

        <scroll-view class="phrases-list" scroll-y>
          <view
            v-for="phrase in currentPhrases"
            :key="phrase.id"
            class="phrase-item"
          >
            <view class="phrase-top">
              <view class="phrase-content">{{ phrase.content }}</view>
            </view>
            <view v-if="phrase.files && phrase.files.length" class="phrase-images">
              <image
                v-for="(file, fileIndex) in phrase.files"
                :key="file.url || fileIndex"
                class="phrase-image"
                :src="file.url"
                mode="aspectFill"
                @click.stop="previewFiles(phrase.files, fileIndex)"
              />
            </view>
            <view class="phrase-actions">
              <view class="action-btn send" @click.stop="sendPhrase(phrase)">
                <uni-icons class="action-icon" type="paperplane" size="18" color="#1f5cff" />
                <text>发送</text>
              </view>

              <template v-if="activeTab === 'mine'">
                <view class="action-btn edit" @click.stop="editPhrase(phrase)">
                  <uni-icons class="action-icon" type="compose" size="18" color="#475467" />
                  <text>编辑</text>
                </view>
                <view class="action-btn delete" @click.stop="deletePhrase(phrase)">
                  <uni-icons class="action-icon" type="trash" size="18" color="#ff3b30" />
                  <text>删除</text>
                </view>
              </template>

              <view
                v-else
                class="action-btn collect"
                :class="{ collected: isFavorite(phrase) }"
                @click.stop="toggleFavorite(phrase)"
              >
                <uni-icons
                  class="action-icon"
                  :type="isFavorite(phrase) ? 'star-filled' : 'star'"
                  size="18"
                  :color="isFavorite(phrase) ? '#1f5cff' : '#667085'"
                />
                <text>{{ isFavorite(phrase) ? "已收藏" : "收藏" }}</text>
              </view>
            </view>
          </view>

          <view v-if="currentPhrases.length === 0" class="empty-state">
            <text class="empty-text">暂无常用语</text>
            <text class="empty-hint">
              {{ activeTab === "mine" ? "可添加快捷回复或收藏更多常用语" : "可在后台常用语库维护后使用" }}
            </text>
          </view>

          <view v-if="activeTab === 'more' && currentPhrases.length > 0" class="collect-tip">
            收藏时默认保存到“我的常用语 > 默认”，可调整目录
          </view>
        </scroll-view>

        <view v-if="activeTab === 'mine'" class="footer-action-bar">
          <view class="add-phrase-btn" @click="showAddPhraseDialog">
            <uni-icons class="add-icon" type="plusempty" size="18" color="#fff" />
            <text class="add-text">添加快捷回复</text>
          </view>
          <view class="edit-btn" @click="toggleEditMode">
            <text class="edit-text">{{ isEditMode ? "完成" : "编辑" }}</text>
          </view>
        </view>
      </view>
    </view>

    <view v-if="showPhrasePopup" class="popup-mask" @click="closePopup">
      <view class="popup-content phrase-popup" @click.stop>
        <view class="popup-header">
          <text class="popup-title">{{ editingPhrase ? "编辑常用语" : "添加常用语" }}</text>
          <view class="popup-close" @click="closePopup">
            <uni-icons class="close-icon" type="closeempty" size="24" color="#98a2b3" />
          </view>
        </view>

        <view class="form-label">所在目录</view>
        <picker
          mode="selector"
          :range="myCategories"
          range-key="name"
          :value="phraseCategoryIndex"
          @change="handlePhraseCategoryChange"
        >
          <view class="category-picker">
            <text>{{ selectedPhraseCategoryName }}</text>
            <uni-icons class="picker-arrow" type="arrowdown" size="16" color="#667085" />
          </view>
        </picker>
        <view class="form-hint">可选择保存到指定目录</view>

        <view class="form-label content-label">常用语内容</view>
        <textarea
          v-model="phraseForm.content"
          class="phrase-textarea"
          placeholder="请输入常用语内容，支持换行"
          maxlength="500"
          :auto-height="false"
        ></textarea>
        <view class="char-count">{{ phraseForm.content.length }}/500</view>

        <form-files
          class="phrase-files-cell"
          :form="phraseForm"
          title="files"
          name="图片附件"
          :max="9"
          @change="handlePhraseFilesChange"
        />

        <view class="popup-actions">
          <button class="cancel-btn" @click="closePopup">取消</button>
          <button class="confirm-btn" @click="savePhrase">保存</button>
        </view>
      </view>
    </view>

    <view v-if="showCollectPopup" class="popup-mask" @click="closeCollectPopup">
      <view class="popup-content collect-popup" @click.stop>
        <view class="popup-header">
          <text class="popup-title">收藏常用语</text>
          <view class="popup-close" @click="closeCollectPopup">
            <uni-icons class="close-icon" type="closeempty" size="24" color="#98a2b3" />
          </view>
        </view>

        <view class="form-label">保存目录</view>
        <picker
          mode="selector"
          :range="myCategories"
          range-key="name"
          :value="collectCategoryIndex"
          @change="handleCollectCategoryChange"
        >
          <view class="category-picker">
            <text>{{ selectedCollectCategoryName }}</text>
            <uni-icons class="picker-arrow" type="arrowdown" size="16" color="#667085" />
          </view>
        </picker>
        <view class="form-hint">收藏后将添加到所选目录</view>

        <view class="collect-preview">{{ collectingPhrase?.content || "" }}</view>
        <view v-if="collectingPhrase?.files && collectingPhrase.files.length" class="phrase-images collect-images">
          <image
            v-for="(file, fileIndex) in collectingPhrase.files"
            :key="file.url || fileIndex"
            class="phrase-image"
            :src="file.url"
            mode="aspectFill"
            @click.stop="previewFiles(collectingPhrase.files, fileIndex)"
          />
        </view>

        <view class="popup-actions">
          <button class="cancel-btn" @click="closeCollectPopup">取消</button>
          <button class="confirm-btn" @click="confirmFavorite">收藏</button>
        </view>
      </view>
    </view>

    <view
      v-if="showCategoryPopup"
      class="popup-mask"
      @click="closeCategoryPopup"
    >
      <view class="popup-content category-popup" @click.stop>
        <view class="popup-header">
          <text class="popup-title">{{ editingCategory ? "编辑分类" : "新建分类" }}</text>
          <view class="popup-close" @click="closeCategoryPopup">
            <uni-icons class="close-icon" type="closeempty" size="24" color="#98a2b3" />
          </view>
        </view>
        <input
          v-model="categoryForm.name"
          class="category-input"
          placeholder="请输入分类名，最多10个字"
        />
        <view class="popup-actions">
          <button class="cancel-btn" @click="closeCategoryPopup">取消</button>
          <button class="confirm-btn" @click="saveCategory">保存</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import { storeToRefs } from "pinia";
import api from "@/utils/api";
import useAccountStore from "@/store/account";
import formFiles from "@/components/form-template/form-cell/form-files.vue";
import { normalizeFileUrl } from "@/utils/file";

const { doctorInfo } = storeToRefs(useAccountStore());

const activeTab = ref("mine");
const isEditMode = ref(false);
const searchKeyword = ref("");
const currentCategory = ref("");

const myCategories = ref([]);
const myPhrases = ref([]);
const corpCategories = ref([]);
const corpPhrases = ref([]);

const showPhrasePopup = ref(false);
const showCategoryPopup = ref(false);
const showCollectPopup = ref(false);
const editingPhrase = ref(null);
const editingCategory = ref(null);
const collectingPhrase = ref(null);

const phraseForm = ref({
  content: "",
  cateId: "",
  files: [],
});

const collectForm = ref({
  cateId: "",
});

const categoryForm = ref({
  name: "",
});

const DEFAULT_CATEGORY_NAME = "默认";

const currentCategories = computed(() => {
  return activeTab.value === "more" ? corpCategories.value : myCategories.value;
});

const currentCategoryName = computed(() => {
  const category = currentCategories.value.find((item) => item.id === currentCategory.value);
  return category ? category.name : "未选择";
});

const firstMyCategory = computed(() => {
  return myCategories.value[0];
});

const defaultMyCategory = computed(() => {
  return myCategories.value.find((item) => item.name === DEFAULT_CATEGORY_NAME);
});

const getFavoriteKey = (id) => (id ? String(id) : "");

const favoriteMap = computed(() => {
  return myPhrases.value.reduce((map, item) => {
    const key = getFavoriteKey(item.sourceCommonWordId);
    if (key) map[key] = item;
    return map;
  }, {});
});

const getCategoryScopeIds = (categories, categoryId) => {
  const ids = [categoryId].filter(Boolean);
  let changed = true;
  while (changed) {
    changed = false;
    categories.forEach((item) => {
      if (item.parentId && ids.includes(item.parentId) && !ids.includes(item.id)) {
        ids.push(item.id);
        changed = true;
      }
    });
  }
  return ids;
};

const currentPhrases = computed(() => {
  const keyword = searchKeyword.value.trim();
  const source = activeTab.value === "more" ? corpPhrases.value : myPhrases.value;
  const scopeIds = getCategoryScopeIds(currentCategories.value, currentCategory.value);
  let list = source.filter((item) => scopeIds.includes(item.cateId));

  if (keyword) {
    list = list.filter((item) => String(item.content || "").includes(keyword));
  }

  return list;
});

const phraseCategoryIndex = computed(() => {
  const index = myCategories.value.findIndex((item) => item.id === phraseForm.value.cateId);
  return index > -1 ? index : 0;
});

const selectedPhraseCategoryName = computed(() => {
  return myCategories.value[phraseCategoryIndex.value]?.name || "请选择目录";
});

const collectCategoryIndex = computed(() => {
  const index = myCategories.value.findIndex((item) => item.id === collectForm.value.cateId);
  return index > -1 ? index : 0;
});

const selectedCollectCategoryName = computed(() => {
  return myCategories.value[collectCategoryIndex.value]?.name || "请选择目录";
});

const normalizeCategory = (item, categoryType) => {
  const name = item.label || item.name || "未命名";
  const isDefault = categoryType === "user" && name === DEFAULT_CATEGORY_NAME;

  return {
    id: item._id || item.id,
    name,
    sort: item.sort || 0,
    level: item.level || 1,
    parentId: item.parentId || "",
    type: categoryType,
    deletable: categoryType === "user" && !isDefault,
    isDefault,
  };
};

const normalizeFiles = (files) => {
  if (!Array.isArray(files)) return [];
  return files
    .map((item, index) => {
      if (typeof item === "string") {
        const url = normalizeFileUrl(item);
        return { type: "image", url, name: getFileDisplayName({ url }, index) };
      }
      const url = item?.url || item?.URL || item?.download_url;
      if (!url) return null;
      return {
        type: item.type || "image",
        url: normalizeFileUrl(url),
        name: getFileDisplayName({ ...item, url }, index),
      };
    })
    .filter(Boolean);
};

const getFileNameFromUrl = (url) => {
  const cleanUrl = String(url || "").split("?")[0].split("#")[0];
  const rawName = cleanUrl.split("/").pop() || "";
  if (!rawName) return "";

  let fileName = rawName;
  try {
    fileName = decodeURIComponent(rawName);
  } catch (error) {
    fileName = rawName;
  }
  return fileName.replace(/^\d{10,}[-_]/, "");
};

const getFileDisplayName = (file, index = 0) => {
  return file?.name || file?.fileName || file?.originalname || getFileNameFromUrl(file?.url || file?.URL || file?.download_url) || `图片${index + 1}`;
};

const normalizePhrase = (item, phraseType) => ({
  id: item._id || item.id,
  cateId: item.cateId || item.categoryId,
  content: item.content || "",
  createTime: item.createTime,
  updateTime: item.updateTime,
  files: normalizeFiles(item.files),
  sourceType: item.sourceType,
  sourceCommonWordId: item.sourceCommonWordId,
  sourceCateId: item.sourceCateId,
  collectTime: item.collectTime,
  collectClient: item.collectClient,
  type: phraseType,
});

const getAccountParams = () => {
  const corpId = doctorInfo.value?.corpId;
  const userId = doctorInfo.value?.userid;
  return { corpId, userId };
};

const isFavorite = (phrase) => Boolean(favoriteMap.value[getFavoriteKey(phrase?.id)]);

const switchTab = (tab) => {
  if (activeTab.value === tab) return;
  activeTab.value = tab;
  isEditMode.value = false;
  searchKeyword.value = "";
  currentCategory.value =
    tab === "mine"
      ? defaultMyCategory.value?.id || firstMyCategory.value?.id || ""
      : corpCategories.value[0]?.id || "";
};

const toggleEditMode = () => {
  isEditMode.value = !isEditMode.value;
};

const handleCategoryClick = (category) => {
  if (activeTab.value === "mine" && isEditMode.value && category.deletable) {
    editCategory(category);
    return;
  }
  currentCategory.value = category.id;
};

const sendPhrase = (phrase) => {
  const pages = getCurrentPages();
  const prevPage = pages[pages.length - 2];
  const files = normalizeFiles(phrase.files);
  const phraseToSend = {
    ...phrase,
    files,
  };

  uni.navigateBack({
    success: () => {
      setTimeout(() => {
        if (!prevPage?.$vm?.sendCommonPhrase) return;
        const result = prevPage.$vm.sendCommonPhrase(phraseToSend);
        if (result && typeof result.then === "function") {
          result.catch((error) => console.error("发送常用语失败:", error));
        }
      }, 200);
    },
  });
};

const showAddPhraseDialog = () => {
  editingPhrase.value = null;
  phraseForm.value = {
    content: "",
    cateId: defaultMyCategory.value?.id || currentCategory.value || firstMyCategory.value?.id || "",
    files: [],
  };
  showPhrasePopup.value = true;
};

const editPhrase = (phrase) => {
  editingPhrase.value = phrase;
  phraseForm.value = {
    content: phrase.content,
    cateId: phrase.cateId || firstMyCategory.value?.id || "",
    files: normalizeFiles(phrase.files),
  };
  showPhrasePopup.value = true;
};

const handlePhraseCategoryChange = (event) => {
  const index = Number(event.detail.value || 0);
  phraseForm.value.cateId = myCategories.value[index]?.id || "";
};

const previewFiles = (files, index = 0) => {
  const urls = normalizeFiles(files).map((item) => item.url).filter(Boolean);
  if (!urls.length) return;
  uni.previewImage({ urls, current: urls[index] || urls[0] });
};

const handlePhraseFilesChange = ({ value }) => {
  phraseForm.value.files = normalizeFiles(value);
};

const savePhrase = async () => {
  if (!phraseForm.value.cateId) {
    const category = await ensureDefaultMyCategory();
    if (!category?.id) {
      uni.showToast({ title: "默认目录不存在", icon: "none" });
      return;
    }
    phraseForm.value.cateId = category.id;
  }
  if (!phraseForm.value.content.trim()) {
    uni.showToast({ title: "请输入内容", icon: "none" });
    return;
  }

  const { corpId, userId } = getAccountParams();
  if (!corpId || !userId) {
    uni.showToast({ title: "请先登录", icon: "none" });
    return;
  }

  try {
    const result = await api("setCommonWords", {
      id: editingPhrase.value?.id,
      cateId: phraseForm.value.cateId,
      content: phraseForm.value.content,
      files: normalizeFiles(phraseForm.value.files),
      corpId,
      userId,
    });

    if (result.success) {
      const nextPhrase = normalizePhrase({
        ...editingPhrase.value,
        ...(result.data || {}),
        _id: editingPhrase.value?.id || result.data?._id,
        cateId: phraseForm.value.cateId,
        content: phraseForm.value.content.trim(),
        files: normalizeFiles(phraseForm.value.files),
      }, "user");

      if (editingPhrase.value) {
        const index = myPhrases.value.findIndex((item) => item.id === editingPhrase.value.id);
        if (index > -1) myPhrases.value.splice(index, 1, nextPhrase);
      } else if (nextPhrase.id) {
        myPhrases.value.unshift(nextPhrase);
      } else {
        await loadMyPhrases();
      }

      uni.showToast({ title: "保存成功", icon: "success" });
      closePopup();
    } else {
      uni.showToast({ title: result.message || "操作失败", icon: "none" });
    }
  } catch (error) {
    console.error("保存常用语失败:", error);
    uni.showToast({ title: "操作失败", icon: "none" });
  }
};

const removeMyPhrase = async (phrase) => {
  const { corpId, userId } = getAccountParams();
  const result = await api("removeCommonWords", {
    id: phrase.id,
    corpId,
    userId,
  });

  if (result.success) {
    const index = myPhrases.value.findIndex((item) => item.id === phrase.id);
    if (index > -1) myPhrases.value.splice(index, 1);
  }
  return result;
};

const createDefaultMyCategory = async () => {
  const { corpId, userId } = getAccountParams();
  if (!corpId || !userId) return null;

  const result = await api("addUserCommonWordCate", {
    label: DEFAULT_CATEGORY_NAME,
    corpId,
    userId,
  });

  if (!result.success) {
    uni.showToast({ title: result.message || "默认目录创建失败", icon: "none" });
    return null;
  }

  await loadMyCategories({ ensureDefault: false });
  return defaultMyCategory.value || firstMyCategory.value || null;
};

const ensureDefaultMyCategory = async () => {
  if (defaultMyCategory.value?.id) return defaultMyCategory.value;
  return await createDefaultMyCategory();
};

const collectPhraseToCategory = async (phrase, cateId) => {
  const { corpId, userId } = getAccountParams();
  const result = await api("setCommonWords", {
    cateId,
    content: phrase.content,
    corpId,
    userId,
    sourceType: "common-words",
    sourceCommonWordId: phrase.id,
    sourceCateId: phrase.cateId,
    collectClient: "wxapp",
    files: normalizeFiles(phrase.files),
  });

  if (result.success) {
    const collectedData = result.data || {};
    const nextPhrase = normalizePhrase({
      ...collectedData,
      _id: collectedData._id || collectedData.id,
      cateId: collectedData.cateId || cateId,
      content: collectedData.content || phrase.content,
      files: collectedData.files || normalizeFiles(phrase.files),
      sourceType: collectedData.sourceType || "common-words",
      sourceCommonWordId: collectedData.sourceCommonWordId || phrase.id,
      sourceCateId: collectedData.sourceCateId || phrase.cateId,
      collectClient: collectedData.collectClient || "wxapp",
      collectTime: collectedData.collectTime || Date.now(),
    }, "user");

    if (nextPhrase.id) {
      const favoriteKey = getFavoriteKey(phrase.id);
      const index = myPhrases.value.findIndex((item) => {
        return item.id === nextPhrase.id || getFavoriteKey(item.sourceCommonWordId) === favoriteKey;
      });
      if (index > -1) {
        myPhrases.value.splice(index, 1, nextPhrase);
      } else {
        myPhrases.value.unshift(nextPhrase);
      }
    } else {
      await loadMyPhrases();
    }
  }

  return result;
};

const deletePhrase = (phrase) => {
  uni.showModal({
    title: "提示",
    content: "确定删除该常用语吗？",
    success: async (res) => {
      if (!res.confirm) return;
      try {
        const result = await removeMyPhrase(phrase);
        if (result.success) {
          uni.showToast({ title: "删除成功", icon: "success" });
        } else {
          uni.showToast({ title: result.message || "删除失败", icon: "none" });
        }
      } catch (error) {
        console.error("删除常用语失败:", error);
        uni.showToast({ title: "删除失败", icon: "none" });
      }
    },
  });
};

const toggleFavorite = async (phrase) => {
  const { corpId, userId } = getAccountParams();
  if (!corpId || !userId) {
    uni.showToast({ title: "请先登录", icon: "none" });
    return;
  }

  try {
    const favorite = favoriteMap.value[getFavoriteKey(phrase.id)];
    if (favorite) {
      const result = await removeMyPhrase(favorite);
      if (result.success) {
        uni.showToast({ title: "已取消收藏", icon: "success" });
      } else {
        uni.showToast({ title: result.message || "取消收藏失败", icon: "none" });
      }
      return;
    }

    const category = await ensureDefaultMyCategory();
    if (!category?.id) {
      uni.showToast({ title: "默认目录不存在", icon: "none" });
      return;
    }

    collectingPhrase.value = phrase;
    collectForm.value.cateId = category.id;
    showCollectPopup.value = true;
  } catch (error) {
    console.error("收藏操作失败:", error);
    uni.showToast({ title: "操作失败", icon: "none" });
  }
};

const handleCollectCategoryChange = (event) => {
  const index = Number(event.detail.value || 0);
  collectForm.value.cateId = myCategories.value[index]?.id || "";
};

const confirmFavorite = async () => {
  const phrase = collectingPhrase.value;
  if (!phrase) {
    closeCollectPopup();
    return;
  }

  if (!collectForm.value.cateId) {
    uni.showToast({ title: "请选择目录", icon: "none" });
    return;
  }

  try {
    const result = await collectPhraseToCategory(phrase, collectForm.value.cateId);
    if (result.success) {
      uni.showToast({ title: "收藏成功", icon: "success" });
      closeCollectPopup();
    } else {
      uni.showToast({ title: result.message || "收藏失败", icon: "none" });
    }
  } catch (error) {
    console.error("收藏操作失败:", error);
    uni.showToast({ title: "操作失败", icon: "none" });
  }
};

const showAddCategoryDialog = () => {
  editingCategory.value = null;
  categoryForm.value.name = "";
  showCategoryPopup.value = true;
};

const editCategory = (category) => {
  if (!category.deletable) return;

  editingCategory.value = category;
  categoryForm.value.name = category.name;
  showCategoryPopup.value = true;
};

const saveCategory = async () => {
  if (!categoryForm.value.name.trim()) {
    uni.showToast({ title: "请输入分类名", icon: "none" });
    return;
  }

  if (categoryForm.value.name.length > 10) {
    uni.showToast({ title: "输入内容超过10个字", icon: "none" });
    return;
  }

  try {
    const { corpId, userId } = getAccountParams();
    const result = await api(editingCategory.value ? "updateUserCommonWordCate" : "addUserCommonWordCate", {
      id: editingCategory.value?.id,
      label: categoryForm.value.name,
      corpId,
      userId,
    });

    if (result.success) {
      await loadMyCategories();
      uni.showToast({ title: "保存成功", icon: "success" });
      closeCategoryPopup();
    } else {
      uni.showToast({ title: result.message || "操作失败", icon: "none" });
    }
  } catch (error) {
    console.error("保存分类失败:", error);
    uni.showToast({ title: "操作失败", icon: "none" });
  }
};

const handleCategoryLongPress = (category) => {
  if (activeTab.value !== "mine" || !category.deletable) return;

  uni.showModal({
    title: "提示",
    content: `确定删除分类"${category.name}"吗？该分类下的常用语也将被删除。`,
    success: (res) => {
      if (res.confirm) deleteCategory(category);
    },
  });
};

const deleteCategory = async (category) => {
  if (!category.deletable) {
    uni.showToast({ title: "该分类不可删除", icon: "none" });
    return;
  }

  try {
    const { corpId, userId } = getAccountParams();
    const result = await api("deleteUserCommonWordCate", {
      id: category.id,
      corpId,
      userId,
    });

    if (result.success) {
      await loadMyCategories();
      await loadMyPhrases();
      currentCategory.value = defaultMyCategory.value?.id || firstMyCategory.value?.id || "";
      uni.showToast({ title: "删除成功", icon: "success" });
    } else {
      uni.showToast({ title: result.message || "删除失败", icon: "none" });
    }
  } catch (error) {
    console.error("删除分类失败:", error);
    uni.showToast({ title: "删除失败", icon: "none" });
  }
};

const closePopup = () => {
  showPhrasePopup.value = false;
  editingPhrase.value = null;
};

const closeCollectPopup = () => {
  showCollectPopup.value = false;
  collectingPhrase.value = null;
  collectForm.value.cateId = "";
};

const closeCategoryPopup = () => {
  showCategoryPopup.value = false;
  editingCategory.value = null;
};

const loadMyCategories = async ({ ensureDefault = true } = {}) => {
  const { corpId, userId } = getAccountParams();
  const result = await api("getUserCommonWordCate", { corpId, userId });
  if (result.success) {
    const list = Array.isArray(result.list) ? result.list : [];
    myCategories.value = list.map((item) => normalizeCategory(item, "user")).filter((item) => item.id);
    if (ensureDefault && !defaultMyCategory.value) {
      await createDefaultMyCategory();
      return;
    }
    if (activeTab.value === "mine") {
      currentCategory.value = currentCategory.value || defaultMyCategory.value?.id || firstMyCategory.value?.id || "";
    }
  } else {
    uni.showToast({ title: result.message || "加载失败", icon: "none" });
  }
};

const loadMyPhrases = async () => {
  const { corpId, userId } = getAccountParams();
  const cateIds = myCategories.value.map((item) => item.id).filter(Boolean);
  if (cateIds.length === 0) {
    myPhrases.value = [];
    return;
  }

  const result = await api("getCommonWordsList", {
    corpId,
    userId,
    cateIds,
    page: 1,
    pageSize: 10000,
  }, false);

  if (result.success) {
    const list = Array.isArray(result.list) ? result.list : [];
    myPhrases.value = list.map((item) => normalizePhrase(item, "user")).filter((item) => item.id);
  }
};

const loadCorpCategories = async () => {
  const { corpId, userId } = getAccountParams();
  const result = await api("getCorpCommonWordCate", { corpId, userId }, false);
  if (result.success) {
    const list = Array.isArray(result.list) ? result.list : [];
    corpCategories.value = list.map((item) => normalizeCategory(item, "corp")).filter((item) => item.id);
    if (activeTab.value === "more" && !currentCategory.value) {
      currentCategory.value = corpCategories.value[0]?.id || "";
    }
  }
};

const loadCorpPhrases = async () => {
  const { corpId, userId } = getAccountParams();
  const cateIds = corpCategories.value.map((item) => item.id).filter(Boolean);
  if (cateIds.length === 0) {
    corpPhrases.value = [];
    return;
  }

  const result = await api("getCommonWordsList", {
    corpId,
    userId,
    cateIds,
    page: 1,
    pageSize: 10000,
  }, false);

  if (result.success) {
    const list = Array.isArray(result.list) ? result.list : [];
    corpPhrases.value = list.map((item) => normalizePhrase(item, "corp")).filter((item) => item.id);
  }
};

const loadAll = async () => {
  const { corpId, userId } = getAccountParams();
  if (!corpId || !userId) {
    uni.showToast({ title: "请先登录", icon: "none" });
    return;
  }

  try {
    await loadMyCategories();
    await loadMyPhrases();
    await loadCorpCategories();
    await loadCorpPhrases();
  } catch (error) {
    console.error("加载常用语失败:", error);
    uni.showToast({ title: "加载失败", icon: "none" });
  }
};

onMounted(() => {
  loadAll();
});
</script>

<style scoped lang="scss">
$primary-color: #1f5cff;
$primary-light: #eef4ff;
$text-main: #222;
$border-color: #edf0f5;

.common-phrases-page {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 20rpx;
  display: flex;
  flex-direction: column;
  background: #f7f8fb;
}

.tabs-bar {
  display: flex;
  height: 96rpx;
  background: #fff;
  border-bottom: 1px solid $border-color;

  .tab-item {
    flex: 1;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #4b5565;
    font-size: 32rpx;
    font-weight: 500;

    &.active {
      color: $primary-color;
      font-weight: 700;

      &::after {
        content: "";
        position: absolute;
        left: 50%;
        bottom: 14rpx;
        width: 70rpx;
        height: 6rpx;
        border-radius: 999rpx;
        background: $primary-color;
        transform: translateX(-50%);
      }
    }
  }
}

.content-wrapper {
  flex: 1;
  min-height: 0;
  display: flex;
  overflow: hidden;
}

.category-sidebar {
  width: 210rpx;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-right: 1px solid $border-color;

  .category-list {
    flex: 1;
    min-height: 0;
  }

  .category-item {
    position: relative;
    min-height: 88rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12rpx 16rpx;
    color: #344054;
    background: #fff;

    &.active {
      color: $primary-color;
      background: $primary-light;

      &::before {
        content: "";
        position: absolute;
        left: 0;
        top: 20rpx;
        bottom: 20rpx;
        width: 4rpx;
        border-radius: 999rpx;
        background: $primary-color;
      }

      .category-name {
        font-weight: 700;
      }
    }
  }

  .category-content {
    position: relative;
    width: 100%;
    text-align: center;
  }

  .category-name {
    font-size: 30rpx;
    line-height: 40rpx;
    word-break: break-all;
  }

  .delete-badge {
    position: absolute;
    top: -22rpx;
    right: -8rpx;
    width: 30rpx;
    height: 30rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #ff3b30;

    .delete-icon {
      color: #fff;
      font-size: 26rpx;
      line-height: 1;
    }
  }

  .add-category-footer {
    min-height: 104rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    border-top: 1px solid $border-color;
    background: #fff;

    .add-category-text {
      color: $primary-color;
      font-size: 30rpx;
      font-weight: 600;
    }
  }
}

.phrases-container {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: #f7f8fb;
}

.list-header {
  padding: 22rpx 24rpx 14rpx;

  .current-title {
    margin-bottom: 16rpx;
    color: $text-main;
    font-size: 30rpx;
    font-weight: 700;
  }
}

.search-box {
  height: 64rpx;
  display: flex;
  align-items: center;
  padding: 0 20rpx;
  border-radius: 32rpx;
  background: #fff;
  border: 1px solid $border-color;

  .search-icon {
    margin-right: 10rpx;
    color: #98a2b3;
    font-size: 32rpx;
  }

  .search-input {
    flex: 1;
    min-width: 0;
    height: 64rpx;
    color: $text-main;
    font-size: 28rpx;
  }

  .clear-search {
    width: 36rpx;
    height: 36rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #98a2b3;
    font-size: 36rpx;
  }
}

.phrases-list {
  flex: 1;
  min-height: 0;
  padding: 0 24rpx 24rpx;
  box-sizing: border-box;
}

.phrase-item {
  margin-bottom: 20rpx;
  padding: 24rpx 24rpx 18rpx;
  border-radius: 14rpx;
  background: #fff;
  border: 1px solid $border-color;
  box-shadow: 0 8rpx 24rpx rgba(16, 24, 40, 0.04);

  .phrase-top {
    display: flex;
    align-items: flex-start;
    gap: 12rpx;
  }

  .phrase-content {
    flex: 1;
    min-width: 0;
    color: $text-main;
    font-size: 30rpx;
    line-height: 44rpx;
    word-break: break-word;
    white-space: pre-wrap;
  }

  .phrase-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0;
    margin-top: 20rpx;
    padding-top: 16rpx;
    border-top: 1px solid $border-color;
  }

  .action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6rpx;
    color: #475467;
    font-size: 28rpx;

    .action-icon {
      font-size: 32rpx;
      line-height: 1;
    }

    &.send,
    &.collect.collected {
      color: $primary-color;
    }

    &.send {
      justify-content: flex-start;
    }

    &.edit {
      justify-content: center;
    }

    &.delete,
    &.collect {
      justify-content: flex-end;
    }

    &.delete {
      color: #ff3b30;
    }
  }
}

.phrase-images {
  display: flex;
  flex-wrap: wrap;
  gap: 12rpx;
  margin-top: 18rpx;
}

.phrase-image {
  width: 96rpx;
  height: 96rpx;
  border-radius: 10rpx;
  background: #f2f4f7;
}

.collect-tip {
  padding: 8rpx 0 28rpx;
  color: #98a2b3;
  font-size: 26rpx;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 180rpx 24rpx;
  text-align: center;

  .empty-text {
    color: #667085;
    font-size: 32rpx;
    font-weight: 600;
  }

  .empty-hint {
    margin-top: 14rpx;
    color: #98a2b3;
    font-size: 26rpx;
  }
}

.footer-action-bar {
  display: flex;
  align-items: center;
  gap: 18rpx;
  padding: 22rpx 24rpx 28rpx;
  background: #fff;
  border-top: 1px solid $border-color;

  .add-phrase-btn {
    flex: 1;
    height: 76rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10rpx;
    color: #fff;
    background: $primary-color;
    border-radius: 18rpx;
    box-shadow: 0 8rpx 20rpx rgba(31, 92, 255, 0.22);
  }

  .add-icon,
  .add-text,
  .edit-text {
    font-size: 30rpx;
    font-weight: 600;
  }

  .edit-btn {
    width: 112rpx;
    height: 76rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    color: $primary-color;
  }
}

.popup-mask {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, 0.45);
}

.popup-content {
  width: 100%;
  padding: 34rpx 32rpx 40rpx;
  box-sizing: border-box;
  background: #fff;
  border-radius: 28rpx 28rpx 0 0;
  box-shadow: 0 -10rpx 30rpx rgba(16, 24, 40, 0.12);

  .popup-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 30rpx;
  }

  .popup-title {
    color: $text-main;
    font-size: 36rpx;
    font-weight: 700;
  }

  .popup-close {
    width: 48rpx;
    height: 48rpx;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .close-icon {
    color: #98a2b3;
    font-size: 48rpx;
    line-height: 1;
  }
}

.form-label {
  margin-bottom: 14rpx;
  color: $text-main;
  font-size: 28rpx;
  font-weight: 600;
}

.content-label {
  margin-top: 30rpx;
}

.category-picker,
.category-input {
  height: 84rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22rpx;
  box-sizing: border-box;
  color: $text-main;
  font-size: 30rpx;
  border: 1px solid #d9e0ea;
  border-radius: 12rpx;
  background: #fff;
}

.picker-arrow {
  color: #667085;
  font-size: 34rpx;
}

.form-hint {
  margin-top: 12rpx;
  color: #98a2b3;
  font-size: 26rpx;
}

.collect-preview {
  margin: 28rpx 0 32rpx;
  padding: 22rpx;
  color: $text-main;
  font-size: 30rpx;
  line-height: 42rpx;
  word-break: break-word;
  white-space: pre-wrap;
  border-radius: 12rpx;
  background: #f7f8fb;
  border: 1px solid $border-color;
}

.collect-images {
  margin: -14rpx 0 32rpx;
}

.phrase-files-cell {
  display: block;
  margin-bottom: 30rpx;

  :deep(.files-wrap) {
    padding: 0;
    border-bottom: 0;
    background: transparent;
  }

  :deep(.files-label) {
    color: $text-main;
    font-size: 30rpx;
    font-weight: 500;
  }
}

.phrase-textarea {
  width: 100%;
  height: 220rpx;
  padding: 22rpx;
  box-sizing: border-box;
  color: $text-main;
  font-size: 30rpx;
  line-height: 42rpx;
  border: 1px solid #d9e0ea;
  border-radius: 12rpx;
  background: #fff;
}

.char-count {
  margin-top: 12rpx;
  margin-bottom: 30rpx;
  color: #98a2b3;
  font-size: 26rpx;
  text-align: right;
}

.category-popup {
  .category-input {
    width: 100%;
    margin-bottom: 32rpx;
  }
}

.popup-actions {
  display: flex;
  gap: 24rpx;

  button {
    flex: 1;
    height: 78rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font-size: 30rpx;
    font-weight: 600;
    border-radius: 14rpx;

    &::after {
      border: 0;
    }
  }

  .cancel-btn {
    color: $text-main;
    background: #fff;
    border: 1px solid #d9e0ea;
  }

  .confirm-btn {
    color: #fff;
    background: $primary-color;
  }
}
</style>
