function setInputReadOnly(input, readonly) {
  if (readonly) {
    input.readOnly = true;
    input.style.cursor = 'not-allowed';
  } else {
    input.readOnly = false;
    input.style.cursor = 'auto';
  }
}
function clearExistingValues() {
  // 清除简单输入框和复选框的值
  document.getElementById("endpoint").value = "clash";
  document.getElementById("sub").value = "";
  document.getElementById("proxy").value = "";
  document.getElementById("refresh").checked = false;
  document.getElementById("autoTest").checked = false;
  document.getElementById("lazy").checked = false;
  document.getElementById("igcg").checked = false;
  document.getElementById("useUDP").checked = false;
  document.getElementById("template").value = "";
  document.getElementById("sort").value = "nameasc";
  document.getElementById("remove").value = "";
  document.getElementById("apiLink").value = "";
  document.getElementById("apiShortLink").value = "";
  // 恢复短链ID和密码输入框状态
  const customIdInput = document.getElementById("customId");
  const passwordInput = document.getElementById("password");
  const generateButton = document.querySelector('button[onclick="generateShortLink()"]');
  customIdInput.value = "";
  setInputReadOnly(customIdInput, false);
  passwordInput.value = "";
  setInputReadOnly(passwordInput, false);
  // 恢复生成短链按钮状态
  generateButton.disabled = false;
  generateButton.classList.remove('btn-secondary');
  generateButton.classList.add('btn-primary');
  document.getElementById("nodeList").checked = false;
  // 清除由 createRuleProvider, createReplace, 和 createRule 创建的所有额外输入组
  clearInputGroup("ruleProviderGroup");
  clearInputGroup("replaceGroup");
  clearInputGroup("ruleGroup");
}
function generateURI() {
  const config = {};
  config.clashType = parseInt(document.getElementById("endpoint").value);
  let subLines = document
    .getElementById("sub")
    .value.split("\n")
    .filter((line) => line.trim() !== "");
  if (subLines.length > 0) {
    config.subscriptions = subLines;
  }
  let proxyLines = document
    .getElementById("proxy")
    .value.split("\n")
    .filter((line) => line.trim() !== "");
  if (proxyLines.length > 0) {
    config.proxies = proxyLines;
  }
  if (
    (config.subscriptions === undefined || config.subscriptions.length === 0) &&
    (config.proxies === undefined || config.proxies.length === 0)
  ) {
    return "";
  }
  config.userAgent = document.getElementById("user-agent").value;
  config.refresh = document.getElementById("refresh").checked;
  config.autoTest = document.getElementById("autoTest").checked;
  config.lazy = document.getElementById("lazy").checked;
  config.nodeList = document.getElementById("nodeList").checked;
  config.ignoreCountryGroup = document.getElementById("igcg").checked;
  config.useUDP = document.getElementById("useUDP").checked;
  const template = document.getElementById("template").value;
  if (template.trim() !== "") {
    config.template = template;
  }
  const ruleProvidersElements = document.getElementsByName("ruleProvider");
  if (ruleProvidersElements.length > 0) {
    const ruleProviders = [];
    for (let i = 0; i < ruleProvidersElements.length / 5; i++) {
      let baseIndex = i * 5;
      let behavior = ruleProvidersElements[baseIndex].value;
      let url = ruleProvidersElements[baseIndex + 1].value;
      let group = ruleProvidersElements[baseIndex + 2].value;
      let prepend = ruleProvidersElements[baseIndex + 3].value;
      let name = ruleProvidersElements[baseIndex + 4].value;
      if (
        behavior.trim() === "" ||
        url.trim() === "" ||
        group.trim() === "" ||
        prepend.trim() === "" ||
        name.trim() === ""
      ) {
        return "";
      }
      ruleProviders.push({
        behavior: behavior,
        url: url,
        group: group,
        prepend: prepend.toLowerCase() === "true",
        name: name,
      });
    }
    if (ruleProviders.length > 0) {
      config.ruleProviders = ruleProviders;
    }
  }
  const rulesElements = document.getElementsByName("rule");
  if (rulesElements.length > 0) {
    const rules = [];
    for (let i = 0; i < rulesElements.length / 2; i++) {
      if (rulesElements[i * 2].value.trim() !== "") {
        let rule = rulesElements[i * 2].value;
        let prepend = rulesElements[i * 2 + 1].value;
        if (rule.trim() === "" || prepend.trim() === "") {
          return "";
        }
        rules.push({
          rule: rule,
          prepend: prepend.toLowerCase() === "true",
        });
      }
    }
    if (rules.length > 0) {
      config.rules = rules;
    }
  }
  config.sort = document.getElementById("sort").value;
  const remove = document.getElementById("remove").value;
  if (remove.trim() !== "") {
    config.remove = remove;
  }
  const replacesElements = document.getElementsByName("replace");
  if (replacesElements.length > 0) {
    const replace = {};
    for (let i = 0; i < replacesElements.length / 2; i++) {
      let replaceStr = replacesElements[i * 2].value;
      let replaceTo = replacesElements[i * 2 + 1].value;
      if (replaceStr.trim() === "") {
        return "";
      }
      replace[replaceStr] = replaceTo;
    }
    if (Object.keys(replace).length > 0) {
      config.replace = replace;
    }
  }
  const jsonString = JSON.stringify(config);
  // 解决 btoa 中文报错,使用 TextEncoder 进行 UTF-8 编码再 base64
  function base64EncodeUnicode(str) {
    const bytes = new TextEncoder().encode(str);
    let binary = '';
    bytes.forEach((b) => binary += String.fromCharCode(b));
    return btoa(binary);
  }
  const encoded = base64EncodeUnicode(jsonString);
  const urlSafeBase64 = encoded
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=/g, "");
  return `convert/${urlSafeBase64}`;
}
// 将输入框中的 URL 解析为参数
async function parseInputURL() {
  // 获取输入框中的 URL
  const inputURL = document.getElementById("urlInput").value;
  // 清除现有的输入框值
  clearExistingValues();
  if (!inputURL) {
    alert("请输入有效的链接!");
    return;
  }
  let url;
  try {
    url = new URL(inputURL);
  } catch (_) {
    alert("无效的链接!");
    return;
  }
  if (url.pathname.includes("/s/")) {
    let hash = url.pathname.substring(url.pathname.lastIndexOf("/s/") + 3);
    let q = new URLSearchParams();
    let password = url.searchParams.get("password");
    if (password === null) {
      alert("仅可解析加密短链");
      return;
    }
    q.append("hash", hash);
    q.append("password", password);
    try {
      const response = await axios.get("./short?" + q.toString());
      url = new URL(response.data, window.location.href);
      // 回显配置链接
      const apiLinkInput = document.querySelector("#apiLink");
      apiLinkInput.value = url.href;
      setInputReadOnly(apiLinkInput, true);
      // 回显短链相关信息
      const apiShortLinkInput = document.querySelector("#apiShortLink");
      apiShortLinkInput.value = inputURL;
      setInputReadOnly(apiShortLinkInput, true);
      // 设置短链ID和密码,并设置为只读
      const customIdInput = document.querySelector("#customId");
      const passwordInput = document.querySelector("#password");
      const generateButton = document.querySelector('button[onclick="generateShortLink()"]');
      customIdInput.value = hash;
      setInputReadOnly(customIdInput, true);
      passwordInput.value = password;
      setInputReadOnly(passwordInput, true);
      // 禁用生成短链按钮
      generateButton.disabled = true;
      generateButton.classList.add('btn-secondary');
      generateButton.classList.remove('btn-primary');
    } catch (error) {
      console.log(error);
      alert("获取短链失败,请检查密码!");
    }
  }
  const pathSections = url.pathname.split("/");
  const convertIndex = pathSections.findIndex((s) => s === "convert");
  if (convertIndex === -1 || convertIndex + 1 >= pathSections.length) {
    alert("无效的配置链接,请确认链接为新版格式。");
    return;
  }
  const base64Config = pathSections[convertIndex + 1];
  let config;
  try {
    const regularBase64 = base64Config.replace(/-/g, "+").replace(/_/g, "/");
    const decodedStr = atob(regularBase64);
    config = JSON.parse(decodeURIComponent(escape(decodedStr)));
  } catch (e) {
    alert("解析配置失败!");
    console.error(e);
    return;
  }
  document.getElementById("endpoint").value = config.clashType || "1";
  if (config.subscriptions) {
    document.getElementById("sub").value = config.subscriptions.join("\n");
  }
  if (config.proxies) {
    document.getElementById("proxy").value = config.proxies.join("\n");
  }
  if (config.refresh) {
    document.getElementById("refresh").checked = config.refresh;
  }
  if (config.autoTest) {
    document.getElementById("autoTest").checked = config.autoTest;
  }
  if (config.lazy) {
    document.getElementById("lazy").checked = config.lazy;
  }
  if (config.template) {
    document.getElementById("template").value = config.template;
  }
  if (config.sort) {
    document.getElementById("sort").value = config.sort;
  }
  if (config.remove) {
    document.getElementById("remove").value = config.remove;
  }
  if (config.userAgent) {
    document.getElementById("user-agent").value = config.userAgent;
  }
  if (config.ignoreCountryGroup) {
    document.getElementById("igcg").checked = config.ignoreCountryGroup;
  }
  if (config.replace) {
    const replaceGroup = document.getElementById("replaceGroup");
    for (const original in config.replace) {
      const div = createReplace();
      div.children[0].value = original;
      div.children[1].value = config.replace[original];
      replaceGroup.appendChild(div);
    }
  }
  if (config.ruleProviders) {
    const ruleProviderGroup = document.getElementById("ruleProviderGroup");
    for (const p of config.ruleProviders) {
      const div = createRuleProvider();
      div.children[0].value = p.behavior;
      div.children[1].value = p.url;
      div.children[2].value = p.group;
      div.children[3].value = p.prepend;
      div.children[4].value = p.name;
      ruleProviderGroup.appendChild(div);
    }
  }
  if (config.rules) {
    const ruleGroup = document.getElementById("ruleGroup");
    for (const r of config.rules) {
      const div = createRule();
      div.children[0].value = r.rule;
      div.children[1].value = r.prepend;
      ruleGroup.appendChild(div);
    }
  }
  if (config.nodeList) {
    document.getElementById("nodeList").checked = config.nodeList;
  }
  if (config.useUDP) {
    document.getElementById("useUDP").checked = config.useUDP;
  }
}
function clearInputGroup(groupId) {
  // 清空第二个之后的child
  const group = document.getElementById(groupId);
  while (group.children.length > 2) {
    group.removeChild(group.lastChild);
  }
}
async function copyToClipboard(elem, e) {
  const apiLinkInput = document.querySelector(`#${elem}`).value;
  try {
    await navigator.clipboard.writeText(apiLinkInput);
    let text = e.textContent;
    e.addEventListener("mouseout", function () {
      e.textContent = text;
    });
    e.textContent = "复制成功";
  } catch (err) {
    console.error("复制到剪贴板失败:", err);
  }
}
function createRuleProvider() {
  const div = document.createElement("div");
  div.classList.add("input-group", "mb-2");
  div.innerHTML = `
            
            
            
            
            
            
        `;
  return div;
}
function createReplace() {
  const div = document.createElement("div");
  div.classList.add("input-group", "mb-2");
  div.innerHTML = `
            
            
            
        `;
  return div;
}
function createRule() {
  const div = document.createElement("div");
  div.classList.add("input-group", "mb-2");
  div.innerHTML = `
            
            
            
        `;
  return div;
}
function listenInput() {
  let selectElements = document.querySelectorAll("select");
  let inputElements = document.querySelectorAll("input");
  let textAreaElements = document.querySelectorAll("textarea");
  inputElements.forEach(function (element) {
    element.addEventListener("input", function () {
      generateURL();
    });
  });
  textAreaElements.forEach(function (element) {
    element.addEventListener("input", function () {
      generateURL();
    });
  });
  selectElements.forEach(function (element) {
    element.addEventListener("change", function () {
      generateURL();
    });
  });
}
function addRuleProvider() {
  const div = createRuleProvider();
  document.getElementById("ruleProviderGroup").appendChild(div);
  listenInput();
}
function addRule() {
  const div = createRule();
  document.getElementById("ruleGroup").appendChild(div);
  listenInput();
}
function addReplace() {
  const div = createReplace();
  document.getElementById("replaceGroup").appendChild(div);
  listenInput();
}
function removeElement(button) {
  button.parentElement.remove();
}
function generateURL() {
  const apiLink = document.getElementById("apiLink");
  let uri = generateURI();
  if (uri === "") {
    return;
  }
  apiLink.value = `${window.location.origin}${window.location.pathname}${uri}`;
  setInputReadOnly(apiLink, true);
}
function generateShortLink() {
  const apiShortLink = document.getElementById("apiShortLink");
  const password = document.getElementById("password");
  const customId = document.getElementById("customId");
  let uri = generateURI();
  if (uri === "") {
    return;
  }
  axios
    .post(
      "./short",
      {
        url: uri,
        password: password.value.trim(),
        customId: customId.value.trim()
      },
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    )
    .then((response) => {
      // 设置返回的短链ID和密码
      customId.value = response.data.hash;
      password.value = response.data.password;
      // 生成完整的短链接
      const shortLink = `${window.location.origin}${window.location.pathname}s/${response.data.hash}?password=${response.data.password}`;
      apiShortLink.value = shortLink;
    })
    .catch((error) => {
      console.log(error);
      if (error.response && error.response.data) {
        alert(error.response.data);
      } else {
        alert("生成短链失败,请重试!");
      }
    });
}
function updateShortLink() {
  const password = document.getElementById("password");
  const apiShortLink = document.getElementById("apiShortLink");
  let hash = apiShortLink.value;
  if (hash.startsWith("http")) {
    let u = new URL(hash);
    hash = u.pathname.substring(u.pathname.lastIndexOf("/s/") + 3);
  }
  if (password.value.trim() === "") {
    alert("请输入原密码进行验证!");
    return;
  }
  let uri = generateURI();
  if (uri === "") {
    return;
  }
  axios
    .put(
      "./short",
      {
        hash: hash,
        url: uri,
        password: password.value.trim(),
      },
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    )
    .then((response) => {
      alert(`短链 ${hash} 更新成功!`);
    })
    .catch((error) => {
      console.log(error);
      if (error.response && error.response.status === 401) {
        alert("密码错误,请输入正确的原密码!");
      } else if (error.response && error.response.data) {
        alert(error.response.data);
      } else {
        alert("更新短链失败,请重试!");
      }
    });
}
// 主题切换功能
function initTheme() {
  const html = document.querySelector('html');
  const themeIcon = document.getElementById('theme-icon');
  let theme;
  // 从localStorage获取用户偏好的主题
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme) {
    // 如果用户之前设置过主题,使用保存的主题
    theme = savedTheme;
  } else {
    // 如果没有设置过,检测系统主题偏好
    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
    theme = prefersDark ? 'dark' : 'light';
  }
  // 设置主题
  html.setAttribute('data-bs-theme', theme);
  // 更新图标
  if (theme === 'dark') {
    themeIcon.textContent = '☀️';
  } else {
    themeIcon.textContent = '🌙';
  }
}
function toggleTheme() {
  const html = document.querySelector('html');
  const currentTheme = html.getAttribute('data-bs-theme');
  // 切换主题
  const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
  html.setAttribute('data-bs-theme', newTheme);
  // 更新图标
  if (newTheme === 'dark') {
    themeIcon.textContent = '☀️';
  } else {
    themeIcon.textContent = '🌙';
  }
  // 保存用户偏好到localStorage
  localStorage.setItem('theme', newTheme);
}
listenInput();
initTheme();