/**
 * 用户注册API路由
 * 作者: 阿瑞
 * 功能: 处理用户注册请求，支持普通注册和邀请注册
 * 版本: 3.0
 */

import { NextRequest, NextResponse } from 'next/server';
import bcrypt from 'bcryptjs';
import { connectSystemDB, RequestWithDB } from '@/lib/db';
import { SystemUserModel } from '@/models/system';
import { WorkspaceStatus, UserStatus } from '@/models/system/types';

/**
 * MySQL查询结果接口
 */
interface MySQLRow {
  [key: string]: string | number | boolean | Date | null;
}

/**
 * MySQL插入结果接口
 */
interface MySQLInsertResult {
  insertId: number;
  affectedRows: number;
}

/**
 * 邀请信息接口
 */
interface InvitationInfo {
  id: number;
  token: string;
  workspace_id: number;
  role?: string;
  role_type?: string;
  role_name?: string;
  is_custom_role?: boolean;
  workspace_name: string;
}

/**
 * 数据库错误接口，扩展了Error接口添加了code属性
 * MySQL错误会包含错误码
 */
interface DbError extends Error {
  code?: string;
  message: string;
}

/**
 * 处理用户注册请求
 * @param req 带数据库连接的请求对象
 */
async function handler(req: RequestWithDB) {
  try {
    // 解析请求体
    const body = await req.json();
    const { username, email, phone, password, workspaceName, inviteToken } = body;

    // 验证必填字段
    if (!username || !email || !phone || !password) {
      return NextResponse.json(
        { 
          success: false, 
          error: '用户名、邮箱、手机号和密码为必填字段' 
        },
        { status: 400 }
      );
    }

    // 如果没有提供邀请令牌，则需要工作空间名称
    if (!inviteToken && !workspaceName) {
      return NextResponse.json(
        { 
          success: false, 
          error: '工作空间名称为必填字段' 
        },
        { status: 400 }
      );
    }

    // 检查用户名是否已存在
    const existingUserByUsername = await SystemUserModel.getByUsername(username);
    if (existingUserByUsername) {
      return NextResponse.json(
        { 
          success: false, 
          error: '用户名已存在' 
        },
        { status: 409 }
      );
    }

    // 检查邮箱是否已存在
    const existingUserByEmail = await SystemUserModel.getByEmail(email);
    if (existingUserByEmail) {
      return NextResponse.json(
        { 
          success: false, 
          error: '邮箱已被注册' 
        },
        { status: 409 }
      );
    }
    
    // 检查手机号是否已存在
    const [existingPhones] = await req.db.query(
      'SELECT id FROM system_users WHERE phone = ?',
      [phone]
    );
    
    if (existingPhones && (existingPhones as MySQLRow[]).length > 0) {
      return NextResponse.json(
        { 
          success: false, 
          error: '手机号已被注册' 
        },
        { status: 409 }
      );
    }
    
    // 对密码进行加密
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(password, salt);

    // 开始注册流程，使用事务确保数据一致性
    try {
      // 开始事务
      await req.db.beginTransaction();
      
      // 初始化变量
      let workspaceId: number | null = null;
      let roleType = "user"; // 默认角色类型
      let roleName = "普通用户"; // 默认角色名称
      let isCustomRole = false; // 默认不是自定义角色
      let invitationId: number | null = null;
      let returnWorkspaceName = workspaceName || '';
      const isInviteFlow = Boolean(inviteToken && inviteToken.trim() !== '');
      
      if (isInviteFlow) {
        // 查询邀请信息
        const [rows] = await req.db.query(
          `SELECT 
            i.id, 
            i.token, 
            i.workspace_id, 
            i.role,
            i.role_type,
            i.role_name,
            i.is_custom_role, 
            w.name as workspace_name
          FROM workspace_invitations i
          JOIN workspaces w ON i.workspace_id = w.id
          WHERE i.token = ? AND i.used_by IS NULL AND i.expires_at > NOW()`,
          [inviteToken]
        );
        
        // 检查是否有结果
        if (!rows || !(rows as MySQLRow[]).length) {
          await req.db.rollback();
          return NextResponse.json(
            { 
              success: false, 
              error: '无效的邀请令牌或已过期' 
            },
            { status: 400 }
          );
        }
        
        // 获取原始邀请记录
        const invitation = (rows as InvitationInfo[])[0];
        
        // 提取邀请信息
        invitationId = Number(invitation.id);
        workspaceId = Number(invitation.workspace_id);
        returnWorkspaceName = String(invitation.workspace_name);
        
        // 获取角色信息
        if (invitation.role_type !== undefined) {
          // 使用新角色系统
          roleType = String(invitation.role_type || 'user');
          roleName = String(invitation.role_name || '普通用户');
          isCustomRole = Boolean(invitation.is_custom_role || false);
        } else {
          // 兼容旧角色系统
          roleType = String(invitation.role || 'user');
          roleName = roleType === 'admin' ? '管理员' : '普通用户';
          isCustomRole = false;
        }
        
        // 验证工作空间ID
        if (!workspaceId || isNaN(workspaceId)) {
          await req.db.rollback();
          return NextResponse.json(
            { 
              success: false, 
              error: '邀请中的工作空间ID无效' 
            },
            { status: 400 }
          );
        }
      } else {
        // 普通注册流程，创建新工作空间
        const [result] = await req.db.query(
          `INSERT INTO workspaces (name, creator_id, status, created_at) VALUES (?, ?, ?, ?)`,
          [workspaceName, 0, WorkspaceStatus.ACTIVE, new Date()]
        );
        
        // 从插入结果中获取ID
        workspaceId = (result as MySQLInsertResult).insertId;
        
        // 管理员角色
        roleType = "admin";
        roleName = "管理员";
        isCustomRole = false;

        if (!workspaceId) {
          await req.db.rollback();
          return NextResponse.json(
            { 
              success: false, 
              error: '创建工作空间失败' 
            },
            { status: 500 }
          );
        }
      }
      
      // 最终检查工作空间ID
      if (workspaceId === null || isNaN(workspaceId) || workspaceId === 0) {
        await req.db.rollback();
        return NextResponse.json(
          { 
            success: false, 
            error: '无法确定工作空间ID' 
          },
          { status: 500 }
        );
      }

      // 创建用户并关联到工作空间
      const [userResult] = await req.db.query(
        `INSERT INTO system_users 
         (username, password, email, phone, workspace_id, role_type, role_name, is_custom_role, status, created_at) 
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          username, 
          hashedPassword, 
          email, 
          phone, 
          workspaceId, 
          roleType,
          roleName,
          isCustomRole, 
          UserStatus.ENABLED,
          new Date()
        ]
      );
      
      const userId = (userResult as MySQLInsertResult).insertId;

      if (!userId) {
        await req.db.rollback();
        return NextResponse.json(
          { 
            success: false, 
            error: '创建用户失败' 
          },
          { status: 500 }
        );
      }
      
      // 如果是普通注册（创建了新工作空间），更新工作空间的创建者ID
      if (!isInviteFlow) {
        await req.db.query(
          `UPDATE workspaces SET creator_id = ?, updated_at = ? WHERE id = ?`,
          [userId, new Date(), workspaceId]
        );
      }
      
      // 如果是邀请注册，更新邀请记录
      if (isInviteFlow && invitationId !== null) {
        await req.db.query(
          `UPDATE workspace_invitations SET used_by = ?, used_at = NOW() WHERE id = ?`,
          [userId, invitationId]
        );
      }

      // 提交事务
      await req.db.commit();

      // 返回注册成功响应
      return NextResponse.json(
        { 
          success: true, 
          message: '注册成功',
          user: { id: userId, username, email },
          workspace: { id: workspaceId, name: returnWorkspaceName }
        }, 
        { status: 201 }
      );
    } catch (error) {
      // 回滚事务
      await req.db.rollback();
      throw error; // 重新抛出错误以便外层catch处理
    }
  } catch (error: unknown) {
    console.error('注册失败:', error);
    
    let statusCode = 500;
    let errorMessage = '注册失败，请稍后再试';
    
    // 处理特定类型的错误
    const dbError = error as DbError;
    if (dbError.code === 'ER_DUP_ENTRY') {
      statusCode = 409;
      errorMessage = '用户名、邮箱或手机号已存在';
    } else if (error instanceof Error) {
      errorMessage = error.message;
    }
    
    return NextResponse.json(
      { 
        success: false, 
        error: errorMessage 
      },
      { status: statusCode }
    );
  }
}

/**
 * 处理用户注册请求
 * POST /api/auth/register
 */
export async function POST(request: NextRequest) {
  try {
    return await connectSystemDB(handler)(request);
  } catch (error) {
    console.error('注册请求处理失败:', error);
    return NextResponse.json(
      { 
        success: false,
        error: '处理注册请求失败'
      },
      { status: 500 }
    );
  }
} 