import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { AuthService } from '../services/index.mt';
import { UserServiceMt } from '@d8d/user-module-mt';
import { z } from '@hono/zod-openapi';
import { AppDataSource } from '@d8d/shared-utils';
import { ErrorSchema } from '@d8d/shared-utils';
import { AuthContext } from '@d8d/shared-types';
import { UserSchemaMt } from '@d8d/user-module-mt';
import { parseWithAwait } from '@d8d/shared-utils';
import { TokenResponseSchema } from '../schemas/index.mt';

const RegisterSchema = z.object({
  username: z.string().min(3).openapi({
    example: 'john_doe',
    description: '用户名'
  }),
  password: z.string().min(6).openapi({
    example: 'password123',
    description: '密码'
  }),
  email: z.string().email().openapi({
    example: 'john@example.com',
    description: '邮箱'
  }).optional()
});


const registerRoute = createRoute({
  method: 'post',
  path: '/register',
  request: {
    body: {
      content: {
        'application/json': {
          schema: RegisterSchema
        }
      }
    }
  },
  responses: {
    201: {
      description: '注册成功',
      content: {
        'application/json': {
          schema: TokenResponseSchema
        }
      }
    },
    400: {
      description: '用户名已存在',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

const app = new OpenAPIHono<AuthContext>().openapi(registerRoute, async (c) => {
  // 在路由处理函数内部初始化服务
  const userService = new UserServiceMt(AppDataSource);
  const authService = new AuthService(userService);

  const { username, password, email } = c.req.valid('json');

  // 从请求头或查询参数中提取租户ID
  const tenantId = c.req.header('X-Tenant-Id') || c.req.query('tenantId');
  const tenantIdNumber = tenantId ? parseInt(tenantId, 10) : undefined;

  const userData: any = { username, password, email };
  // 如果提供了租户ID，则设置租户ID
  if (tenantIdNumber) {
    userData.tenantId = tenantIdNumber;
  }

  const user = await userService.createUser(userData, tenantIdNumber);
  const token = authService.generateToken(user);
  return c.json({
    token,
    user: await parseWithAwait(UserSchemaMt, user)
  }, 201);
});

export default app;