import { PageTitleUpdatedEvent } from 'electron';
import { TabGroup, Tab } from 'electron-tabs';
import { MenuItem, ApiResponse } from './EIAC_Desktop_Api';

// 保存最后一个无效URL的结果
let lastInvalidUrlResult: { url: string, message: string, status: number } | null = null;
const tabGroup: TabGroup = document.querySelector('tab-group') as TabGroup;

/**
 * 检查登录状态
 */
function checkLoginStatus(): void {
  const cookie = window.electronAPI.getSessionStorage('cookies');
  if (!cookie) {
    window.location.href = 'login.html';
    return;
  }

  // Show user information
  const userInfo = document.getElementById('userInfo');
  if (userInfo) {
    userInfo.textContent = '欢迎使用';
  }
}

/**
 * 获取菜单列表
 * @returns 菜单列表
 */
async function getMenuListAsync(): Promise<MenuItem[]> {
  try {
    const response: ApiResponse<MenuItem[]> = await window.electronAPI.getMenuCacheAsync();
    if (response.status === 0) {
      return response.data;
    } else {
      throw new Error(response.msg || '获取菜单列表失败');
    }
  } catch (error) {
    console.error(error);
    throw error;
  }
}

/**
 * 创建菜单项
 * @param item 菜单项
 * @param menuList 菜单列表
 * @returns 菜单项
 */
function createMenuItem(item: MenuItem, menuList: MenuItem[]): HTMLLIElement {
  const li: HTMLLIElement = document.createElement('li');
  li.className = 'menu-item';

  const icon: HTMLImageElement = document.createElement('img');
  icon.src = item.IconConfig._1x.Default;
  icon.alt = item.ShowName;
  icon.className = 'menu-icon';

  const span: HTMLSpanElement = document.createElement('span');
  span.textContent = item.ShowName;

  li.appendChild(icon);
  li.appendChild(span);

  if (item.Url) {
    li.addEventListener('click', async () => {
      // Remove active state from other menu items
      document.querySelectorAll('.menu-item').forEach(menuItem => {
        menuItem.classList.remove('active');
        const menuIcon = menuItem.querySelector('.menu-icon') as HTMLImageElement;
        if (menuIcon) {
          const menuItemData = menuList.find((m: MenuItem) => m.ShowName === menuItem.querySelector('span')?.textContent);
          if (menuItemData) {
            menuIcon.src = menuItemData.IconConfig._1x.Default;
          }
        }
      });

      // Add active state to current menu item
      li.classList.add('active');
      icon.src = item.IconConfig._1x.Selected;

      // Create new tab
      await addTabAsync(tabGroup, item);
    });
  }

  return li;
}

/**
 * 渲染菜单
 * @param menuList 菜单列表
 */
function renderMenu(menuList: MenuItem[]): void {
  const menuContainer: HTMLUListElement = document.getElementById('menuList') as HTMLUListElement;
  if (!menuContainer) return;

  menuList.forEach(item => {
    const menuItem: HTMLLIElement = createMenuItem(item, menuList);
    menuContainer.appendChild(menuItem);

    if (item.Children) {
      const subMenu: HTMLUListElement = document.createElement('ul');
      subMenu.className = 'submenu';
      item.Children.forEach(child => {
        const childItem: HTMLLIElement = createMenuItem(child, menuList);
        subMenu.appendChild(childItem);
      });
      menuContainer.appendChild(subMenu);
    }
  });
}

/**
 * 添加标签页
 * @param tabGroup 标签组
 * @param menuItem 菜单项
 * @param allowCloseTab 是否允许关闭标签页
 * @returns 标签页
 */
async function addTabAsync(tabGroup: TabGroup, menuItem: MenuItem, allowCloseTab: boolean = true): Promise<Tab | null> {
  const url: string = menuItem.Url.startsWith("http") ? menuItem.Url : `http://${menuItem.Url}`;
  const result: { ok: boolean; status: number; message?: string } = await window.electronAPI.checkUrlAvailable(url);
  if (result.ok && result.status >= 200 && result.status < 400) {
    console.log(`✅ URL ${url} 可访问:`, result.status);
    lastInvalidUrlResult = null;

    const cookies: string = window.electronAPI.getSessionStorage('cookies');
    await window.electronAPI.setWebviewCookie(url, cookies);
  } else {
    console.warn(`❌ URL ${url} 不可访问:`, result.message ?? `status ${result.status}`);
    lastInvalidUrlResult = { url, message: result.message, status: result.status };

    const helpDescrip: string = await window.electronAPI.getHelperDescripAsync(result.status.toString()) ?? `无法访问{URL}\r\n异常原因:${result.message ?? `status ${result.status}`}\r\n请联系技术支持。`;
    showErrorModal(helpDescrip.replace('{URL}', url));
    return null;
  }

  const zoomFactor: number = await window.electronAPI.getZoomFactorByUrl(url);

  const tab: Tab = tabGroup.addTab({
    active: true,
    closable: allowCloseTab,
    title: menuItem.ShowName,
    src: url,
    iconURL: menuItem.IconConfig._1x.Default,
    webviewAttributes: {
      'webpreferences': 'contextIsolation=yes, nodeIntegration=no',
      'autosize': 'on',
      'allowpopups': true
    },
    ready: (tab: Tab) => {
      // 在webview加载完成后,获取并设置标签页的标题和图标
      const webview: Electron.WebviewTag = tab.webview as Electron.WebviewTag;
      listenWebviewTitleChange(webview, tab);

      tab.once('webview-dom-ready', () => {
        const webview: Electron.WebviewTag = tab.webview as Electron.WebviewTag;
        const defaultZoomFactor: number = webview.getZoomFactor();
        console.log('Default zoom factor:', defaultZoomFactor);

        if (defaultZoomFactor != zoomFactor) {
          webview.setZoomFactor(zoomFactor);
          console.log('Modify zoom factor:', zoomFactor);
        } else {
          console.log('Default zoom factor is the same as the zoom factor:', zoomFactor);
        }
      });
    }
  });

  return tab;
}

/**
 * 监听webview的标题变化,并更新标签页的标题和图标
 * @param webview webview
 * @param tab 标签页
 */
function listenWebviewTitleChange(webview: Electron.WebviewTag, tab: Tab): void {
  // 在webview加载完成后,获取并设置标签页的标题和图标
  webview.addEventListener('did-finish-load', async () => {
    const title: string = webview.getTitle();
    tab.setTitle(title);
    console.log('did-finish-load title:', title);

    const faviconUrl: string = await getFaviconUrl(webview);
    console.log('did-finish-load iconUrl:', faviconUrl);
    if (faviconUrl) {
      tab.setIcon(faviconUrl, null);
    }
  });

  // 监听webview的标题变化,并更新标签页的标题和图标
  webview.addEventListener('page-title-updated', async (event: PageTitleUpdatedEvent) => {
    console.log('title-changed title:', event.title);
    tab.setTitle(event.title);

    const faviconUrl: string = await getFaviconUrl(webview);
    console.log('title-changed iconUrl:', faviconUrl);
    if (faviconUrl) {
      tab.setIcon(faviconUrl, null);
    }
  });
}

/**
 * 获取图标URL
 * @param webview webview
 * @returns 图标URL
 */
async function getFaviconUrl(webview: Electron.WebviewTag): Promise<string> {
  const iconUrl: string | null = await webview.executeJavaScript(`
      (() => {
        const relList = ['icon', 'shortcut icon', 'apple-touch-icon'];
        const links = Array.from(document.getElementsByTagName('link'));
        const iconLink = links.find(link => relList.includes(link.rel));
        return iconLink ? iconLink.href : null;
      })();
    `);

  if (iconUrl) {
    return iconUrl;
  }

  const url: string = webview.getURL();
  const defaultFaviconUrl: string = new URL(url).origin + '/favicon.ico';
  return defaultFaviconUrl;
}

/**
 * 绑定Help图标点击事件
 */
function bindHelpIconClickEvent(menuItem: MenuItem): void {
  const helpIcon: HTMLImageElement = document.getElementById('helpIcon') as HTMLImageElement;
  helpIcon.src = menuItem.IconConfig._1x.Default;
  helpIcon.addEventListener('mouseenter', (event) => helpIcon.src = menuItem.IconConfig._1x.Selected);
  helpIcon.addEventListener('mouseleave', () => helpIcon.src = menuItem.IconConfig._1x.Default);
  helpIcon.addEventListener('click', async (event) => {
    if (lastInvalidUrlResult) {
      const helpDescrip: string = await window.electronAPI.getHelperDescripAsync(lastInvalidUrlResult.status.toString()) ?? `无法访问{URL}\r\n异常原因:${lastInvalidUrlResult.message ?? `status ${lastInvalidUrlResult.status}`}\r\n请联系技术支持。`;
      showErrorModal(helpDescrip.replace('{URL}', lastInvalidUrlResult.url));
    } else {
      const tab: Tab | null = tabGroup.tabs.find(tab => (tab.webview as Electron.WebviewTag).getURL() === menuItem.Url);
      if (tab) {
        tab.activate();
      } else {
        await addTabAsync(tabGroup, menuItem);
      }
    }
  });
}

/**
 * 绑定logo点击事件
 */
function bindLogoClickEvent(tabGroup: TabGroup, menuItem: MenuItem): void {
  const logo: HTMLImageElement = document.getElementById('logo') as HTMLImageElement;
  logo.addEventListener('click', async () => {
    console.log('logo clicked');

    // 先检查是否已经打开过该标签页,如果打开过,则直接激活该标签页,否则打开新标签页
    const tab: Tab | null = tabGroup.tabs.find(tab => (tab.webview as Electron.WebviewTag).getURL() === menuItem.Url);
    if (tab) {
      tab.activate();
    } else {
      const newTab: Tab | null = await addTabAsync(tabGroup, menuItem);
      if (newTab) {
        newTab.setPosition(0);
      }
    }
  });
}

/**
 * 绑定登出事件
 */
function bindLogoutEvent(): void {
  const logoutBtn: HTMLButtonElement = document.getElementById('btnLogout') as HTMLButtonElement;
  if (logoutBtn) {
    logoutBtn.addEventListener('click', () => {
      window.electronAPI.removeSessionStorage('cookies');
      window.location.href = 'login.html';
    });
  }
}

let closeCount: number = 0;
/**
 * 绑定错误弹窗事件
 */
function bindErrorModalEvent(): void {
  const errorModal: HTMLDivElement = document.getElementById('errorModal') as HTMLDivElement;
  const closeErrorModal: HTMLButtonElement = document.getElementById('closeErrorModal') as HTMLButtonElement;
  const faultReporting: HTMLButtonElement = document.getElementById('faultReporting') as HTMLButtonElement;

  faultReporting.addEventListener('click', async () => await faultReportingAsync());

  // Close button click event
  closeErrorModal.addEventListener('click', () => {
    errorModal.style.display = 'none';
    closeCount++;

    // 如果关闭次数大于等于2,则重置计数并且清空lastInvalidUrlResult
    if (closeCount >= 2) {
      closeCount = 0;
      lastInvalidUrlResult = null;
    }
  });

  // Click outside to close
  window.addEventListener('click', (event: Event) => {
    if (event.target === errorModal) {
      errorModal.style.display = 'none';
      closeCount++;

      // 如果关闭次数大于等于2,则重置计数并且清空lastInvalidUrlResult
      if (closeCount >= 2) {
        closeCount = 0;
        lastInvalidUrlResult = null;
      }
    }
  });
}

/**
 * 显示错误弹窗
 * @param message 错误消息
 */
function showErrorModal(message: string): void {
  const errorModal: HTMLDivElement = document.getElementById('errorModal') as HTMLDivElement;
  const errorMessage: HTMLParagraphElement = document.getElementById('errorMessage') as HTMLParagraphElement;
  errorMessage.textContent = message;
  errorModal.style.display = 'block';
}

/**
 * 故障上报
 */
async function faultReportingAsync(): Promise<void> {
  if (lastInvalidUrlResult) {
    const faultReportingBtn = document.getElementById('faultReporting') as HTMLButtonElement;
    const originalText = faultReportingBtn.textContent;

    try {
      // 显示请求中状态
      faultReportingBtn.disabled = true;
      faultReportingBtn.textContent = '上报中...';

      const result: { ok: boolean; status: number; message?: string } = await window.electronAPI.faultReporting(
        lastInvalidUrlResult.url,
        lastInvalidUrlResult.message,
        lastInvalidUrlResult.status
      );

      // 显示请求结果
      if (result.ok) {
        lastInvalidUrlResult = null;
        faultReportingBtn.textContent = '上报成功';
        faultReportingBtn.style.backgroundColor = '#4CAF50';
        setTimeout(() => {
          faultReportingBtn.textContent = originalText;
          faultReportingBtn.style.backgroundColor = '';
          faultReportingBtn.disabled = false;
          // 关闭错误弹窗
          const errorModal = document.getElementById('errorModal') as HTMLDivElement;
          errorModal.style.display = 'none';
        }, 2000);
      } else {
        faultReportingBtn.textContent = '上报失败';
        faultReportingBtn.style.backgroundColor = '#f44336';
        setTimeout(() => {
          faultReportingBtn.textContent = originalText;
          faultReportingBtn.style.backgroundColor = '';
          faultReportingBtn.disabled = false;
        }, 2000);
      }
    } catch (error) {
      console.error('故障上报异常:', error);
      faultReportingBtn.textContent = '上报异常';
      faultReportingBtn.style.backgroundColor = '#f44336';
      setTimeout(() => {
        faultReportingBtn.textContent = originalText;
        faultReportingBtn.style.backgroundColor = '';
        faultReportingBtn.disabled = false;
      }, 2000);
    }
  }
}

/**
 * 初始化
 */
async function initialize(): Promise<void> {
  // Check login status
  checkLoginStatus();

  try {
    const menuList: MenuItem[] = await getMenuListAsync();
    renderMenu(menuList);

    // Create initial tab
    const firstMenuItem: MenuItem = menuList[0];
    await addTabAsync(tabGroup, firstMenuItem, false);

    // Bind help icon click event
    const helpMenuItem: MenuItem = menuList[menuList.length - 2];
    bindHelpIconClickEvent(helpMenuItem);

    // Bind logo click event
    const logoMenuItem: MenuItem = menuList[menuList.length - 1];
    bindLogoClickEvent(tabGroup, logoMenuItem);

    // Bind logout event
    bindLogoutEvent();

    // Bind error modal event
    bindErrorModalEvent();
  } catch (error) {
    console.error('初始化失败:', error);
  }
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', initialize);

// 监听新标签页打开事件
window.electronAPI.onOpenTab((webContentId: number, url: string) => {
  const defaultFaviconUrl = new URL(url).origin + '/favicon.ico';
  addTabAsync(tabGroup, {
    Url: url,
    ShowName: '新标签页',
    IconConfig: { _1x: { Default: defaultFaviconUrl, Selected: defaultFaviconUrl }, _2x: { Default: defaultFaviconUrl, Selected: defaultFaviconUrl } },
    Children: null
  });
});