import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
import { ErrorSchema } from '@/server/utils/errorHandler';
import { AuthContext } from '@/server/types/context';
import { authMiddleware } from '@/server/middleware/auth.middleware';
import * as process from 'node:process'

// 配置信息
const IM_APP_ID = process.env.IM_APP_ID || '';
const IM_APP_KEY = process.env.IM_APP_KEY || '';
const IM_APP_SIGN = process.env.IM_APP_SIGN || '';
const RTC_APP_ID = process.env.RTC_APP_ID || '';
const RTC_APP_KEY = process.env.RTC_APP_KEY || '';
// 请求和响应Schema定义
const CreateImTokenRequest = z.object({
  role: z.string().openapi({
    description: '用户角色',
    example: 'teacher'
  })
});

const ImTokenResponse = z.object({
  nonce: z.string().openapi({ description: '随机字符串' }),
  token: z.string().openapi({ description: 'IM认证令牌' }),
  timestamp: z.number().openapi({ description: '时间戳' }),
  appId: z.string().openapi({ description: '应用ID' }),
  appSign: z.string().openapi({ description: '应用签名' })
});

const CreateRtcTokenRequest = z.object({
  channelId: z.string().openapi({
    description: '频道ID',
    example: 'classroom_123'
  })
});

const RtcTokenResponse = z.object({
  token: z.string().openapi({ description: 'RTC认证令牌' }),
  timestamp: z.number().openapi({ description: '时间戳' }),
  appId: z.string().openapi({ description: '应用ID' })
});

const hex = (buffer: ArrayBuffer): string => {
  const hexCodes = [];
  const view = new DataView(buffer);
  for (let i = 0; i < view.byteLength; i += 4) {
    const value = view.getUint32(i);
    const stringValue = value.toString(16);
    const padding = '00000000';
    const paddedValue = (padding + stringValue).slice(-padding.length);
    hexCodes.push(paddedValue);
  }
  return hexCodes.join('');
};

const generateRTCToken = async (
  channelId: string,
  userId: string
): Promise<{
  token: string;
  timestamp: number;
}> => {
  const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
  const encoder = new TextEncoder();
  const data = encoder.encode(`${RTC_APP_ID}${RTC_APP_KEY}${channelId}${userId}${timestamp}`);
  const hash = await crypto.subtle.digest('SHA-256', data);
  const token = hex(hash);
  return {
    token,
    timestamp
  }
};

const generateImToken = async (userId: string, role: string): Promise<{
  nonce: string;
  token: string;
  timestamp: number;
}> => {
  const nonce = 'AK_4';
  const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
  const pendingShaStr = `${IM_APP_ID}${IM_APP_KEY}${userId}${nonce}${timestamp}${role}`;
  const encoder = new TextEncoder();
  const data = encoder.encode(pendingShaStr);
  const hash = await crypto.subtle.digest('SHA-256', data);
  const token = hex(hash);
  return {
    nonce,
    token,
    timestamp
  }
};

// 创建IM Token路由
const createImTokenRoute = createRoute({
  method: 'post',
  path: '/im_token',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: CreateImTokenRequest }
      }
    }
  },
  responses: {
    200: {
      description: '成功生成IM Token',
      content: { 'application/json': { schema: ImTokenResponse } }
    },
    401: {
      description: '未授权',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '服务器错误',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 创建RTC Token路由
const createRtcTokenRoute = createRoute({
  method: 'post',
  path: '/rtc_token',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: CreateRtcTokenRequest }
      }
    }
  },
  responses: {
    200: {
      description: '成功生成RTC Token',
      content: { 'application/json': { schema: RtcTokenResponse } }
    },
    401: {
      description: '未授权',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '服务器错误',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 创建API应用实例
const app = new OpenAPIHono<AuthContext>()
  .openapi(createImTokenRoute, async (c) => {
    try {
      const { role } = c.req.valid('json');
      const user = c.get('user');

      if (!user || typeof user !== 'object' || !('id' in user)) {
        return c.json({ code: 401, message: '用户信息无效' }, 401);
      }

      const { nonce, token, timestamp } = await generateImToken(user.id.toString(), role);

      return c.json({
        nonce,
        token,
        timestamp,
        appId: IM_APP_ID,
        appSign: IM_APP_SIGN,
      }, 200);
    } catch (error) {
      console.error('生成IM Token失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '生成IM Token失败'
      }, 500);
    }
  })
  .openapi(createRtcTokenRoute, async (c) => {
    try {
      const { channelId } = c.req.valid('json');
      const user = c.get('user');

      if (!user || typeof user !== 'object' || !('id' in user)) {
        return c.json({ code: 401, message: '用户信息无效' }, 401);
      }

      if (!RTC_APP_ID || !RTC_APP_KEY) {
        return c.json({ code: 500, message: '服务配置不完整' }, 500);
      }

      const { token, timestamp } = await generateRTCToken(channelId, user.id.toString());

      return c.json({
        token,
        timestamp,
        appId: RTC_APP_ID,
      }, 200);
    } catch (error) {
      console.error('生成RTC Token失败:', error);
      return c.json({
        code: 500,
        message: error instanceof Error ? error.message : '生成RTC Token失败'
      }, 500);
    }
  });

export default app;