/**
@desc
请您帮我设计一个ionic/angular项目的TokenGuard路由守卫，检查localStorage是否有token值。若不存在，通过dom构建ui交互提示用户填写token（不使用modal和angular逻辑）。若存在token或填写后，则调用接口：
curl -X GET \
  -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H "X-Parse-Session-Token: r:pnktnjyb996sj4p156gjtp4im" \
  https://YOUR.PARSE-SERVER.HERE/parse/users/me 
可用fetch请求验证token是否正常。
若不正常，提示错误请重新填写直到填写了有效token。
若正常则返回true。
接口地址为https://server.fmode.cn/parse 应用id为 ncloudmaster。

@example 路由守卫使用
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TokenGuard } from './guards/token.guard';

const routes: Routes = [
  {
    path: 'protected',
    loadChildren: () => import('./protected/protected.module').then(m => m.ProtectedPageModule),
    canActivate: [TokenGuard]
  },
  // 其他路由...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

 */

// src/app/guards/token.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class TokenGuard implements CanActivate {
  private readonly PARSE_SERVER_URL = 'https://server.fmode.cn/parse';
  private readonly APPLICATION_ID = 'ncloudmaster';

  constructor(
    private http: HttpClient,
    private router: Router
  ) {}

  async canActivate(): Promise<boolean> {
    let token = localStorage.getItem('parseSessionToken');

    if (!token) {
      token = await this.showTokenPrompt();
      if (!token) {
        this.router.navigate(['/login']);
        return false;
      }
    }

    const isValid = await this.validateToken(token);
    if (!isValid) {
      localStorage.removeItem('parseSessionToken');
      return this.canActivate();
    }

    localStorage.setItem('parseSessionToken', token);
    return true;
  }

  private async validateToken(token: string): Promise<boolean> {
    const headers = new HttpHeaders({
      'X-Parse-Application-Id': this.APPLICATION_ID,
      'X-Parse-Session-Token': token
    });

    try {
      const response: any = await this.http.get(
        `${this.PARSE_SERVER_URL}/users/me`,
        { headers }
      ).toPromise();
      return !!response?.objectId;
    } catch (error) {
      return false;
    }
  }

  private showTokenPrompt(): Promise<string | null> {
    return new Promise((resolve) => {
      // 创建遮罩层
      const overlay = document.createElement('div');
      overlay.style.position = 'fixed';
      overlay.style.top = '0';
      overlay.style.left = '0';
      overlay.style.width = '100%';
      overlay.style.height = '100%';
      overlay.style.backgroundColor = 'rgba(0,0,0,0.5)';
      overlay.style.display = 'flex';
      overlay.style.justifyContent = 'center';
      overlay.style.alignItems = 'center';
      overlay.style.zIndex = '1000';

      // 创建对话框
      const dialog = document.createElement('div');
      dialog.style.backgroundColor = 'white';
      dialog.style.padding = '20px';
      dialog.style.borderRadius = '8px';
      dialog.style.width = '80%';
      dialog.style.maxWidth = '400px';

      // 创建标题
      const title = document.createElement('h3');
      title.textContent = '请输入 Token';
      title.style.marginTop = '0';
      title.style.color = "black";
      dialog.appendChild(title);

      // 创建描述
      // 使用以下指令获取token
      
      const descEl:HTMLElement = document.createElement("div");
      descEl.innerHTML = `获取token方法：<br>
      1.登录<a href="https://ai.fmode.cn" target="_blank">https://ai.fmode.cn</a><br>
      2.按F12进入调试——打开控制台Console<br>
      3.输入指令：<br>
      <span style="color:blue;">JSON.parse(localStorage.getItem("Parse/ncloudmaster/currentUser"))?.sessionToken</span><br>
      4.复制字符串内容，形如：<br>
      <span style="color:red">r:xxxxxxxxxxxxx</span>
      `
      descEl.style.color = "black"
      dialog.appendChild(descEl);

      // 创建错误消息容器
      const errorMsg = document.createElement('div');
      errorMsg.style.color = 'red';
      errorMsg.style.minHeight = '20px';
      errorMsg.style.margin = '10px 0';
      dialog.appendChild(errorMsg);

      // 创建输入框
      const input = document.createElement('input');
      input.type = 'text';
      input.placeholder = '请输入您的 Token';
      input.style.width = '100%';
      input.style.padding = '10px';
      input.style.marginBottom = '15px';
      input.style.boxSizing = 'border-box';
      dialog.appendChild(input);

      // 创建按钮容器
      const buttonContainer = document.createElement('div');
      buttonContainer.style.display = 'flex';
      buttonContainer.style.justifyContent = 'flex-end';
      buttonContainer.style.gap = '10px';

      // 创建提交按钮
      const submitBtn = document.createElement('button');
      submitBtn.textContent = '提交';
      submitBtn.style.padding = '8px 16px';
      submitBtn.style.backgroundColor = '#3880ff';
      submitBtn.style.color = 'white';
      submitBtn.style.border = 'none';
      submitBtn.style.borderRadius = '4px';
      submitBtn.disabled = true;

      // 创建取消按钮
      const cancelBtn = document.createElement('button');
      cancelBtn.textContent = '取消';
      cancelBtn.style.padding = '8px 16px';
      cancelBtn.style.backgroundColor = '#eb445a';
      cancelBtn.style.color = 'white';
      cancelBtn.style.border = 'none';
      cancelBtn.style.borderRadius = '4px';

      // 添加按钮到容器
      buttonContainer.appendChild(cancelBtn);
      buttonContainer.appendChild(submitBtn);
      dialog.appendChild(buttonContainer);

      // 添加到遮罩层
      overlay.appendChild(dialog);
      document.body.appendChild(overlay);

      // 自动聚焦输入框
      input.focus();

      // 输入验证
      input.addEventListener('input', () => {
        submitBtn.disabled = !input.value.trim();
      });

      // 取消按钮事件
      const cleanup = () => {
        document.body.removeChild(overlay);
      };

      cancelBtn.addEventListener('click', () => {
        cleanup();
        resolve(null);
      });

      // 提交按钮事件
      submitBtn.addEventListener('click', async () => {
        const token = input.value.trim();
        if (!token) return;

        const isValid = await this.validateToken(token);
        if (isValid) {
          cleanup();
          resolve(token);
        } else {
          errorMsg.textContent = 'Token 无效，请重新输入';
          input.value = '';
          submitBtn.disabled = true;
          input.focus();
        }
      });

      // 回车键提交
      input.addEventListener('keypress', async (e) => {
        if (e.key === 'Enter' && input.value.trim()) {
          const token = input.value.trim();
          const isValid = await this.validateToken(token);
          
          if (isValid) {
            cleanup();
            resolve(token);
          } else {
            errorMsg.textContent = 'Token 无效，请重新输入';
            input.value = '';
            submitBtn.disabled = true;
            input.focus();
          }
        }
      });
    });
  }
}