import { Request, Response, NextFunction } from 'express';
import { AuthService } from '../../services/AuthService';
import { z } from 'zod';
import { logger } from '../../utils/logger';
import { UserRole } from '../../models/User';

const loginSchema = z.object({
  username: z.string().min(1),
  password: z.string().min(1),
});

const refreshTokenSchema = z.object({
  refreshToken: z.string().min(1),
});

const registerSchema = z.object({
  username: z.string().min(1),
  password: z.string().min(6),
  role: z.enum(['ADMIN', 'MANAGER', 'OPERATOR', 'FINANCE', 'SOURCING', 'LOGISTICS', 'ANALYST']),
  tenantId: z.string().min(1),
  shopId: z.string().optional(),
});

const mfaEnableSchema = z.object({
  method: z.enum(['TOTP', 'SMS', 'EMAIL']),
  secret: z.string().min(1),
});

const mfaVerifySchema = z.object({
  method: z.enum(['TOTP', 'SMS', 'EMAIL']),
  code: z.string().min(1),
});

const oauth2AuthorizeSchema = z.object({
  client_id: z.string().min(1),
  redirect_uri: z.string().min(1),
  response_type: z.string().min(1),
  scope: z.string().optional(),
  state: z.string().optional(),
});

const oauth2TokenSchema = z.object({
  grant_type: z.string().min(1),
  client_id: z.string().min(1),
  client_secret: z.string().min(1),
  code: z.string().optional(),
  redirect_uri: z.string().optional(),
  refresh_token: z.string().optional(),
});

const oauth2ClientSchema = z.object({
  client_id: z.string().min(1),
  client_secret: z.string().min(1),
  redirect_uri: z.string().min(1),
  grant_types: z.string().min(1),
  scope: z.string().min(1),
  tenant_id: z.string().min(1),
});

/**
 * [CORE_AUTH_01] 多租户身份中心控制器
 */
export class AuthController {
  /**
   * 登录接口: 校验身份并颁发 JWT (含租户上下文)
   */
  static async login(req: Request, res: Response, next: NextFunction) {
    try {
      const { username, password } = loginSchema.parse(req.body);
      const result = await AuthService.login({
        tenantId: 'default-tenant',
        shopId: 'default-shop',
        taskId: 'login-task',
        traceId: 'login-trace',
        businessType: 'TOC',
        username,
        password,
        rememberMe: false
      });

      if (!result.success) {
        return res.status(401).json({ success: false, error: result.error || 'Invalid credentials' });
      }

      // 模拟用户对象
      const user = {
        id: 'mock-user-id',
        username,
        role: 'OPERATOR',
        tenantId: 'default-tenant',
        shopId: 'default-shop',
        status: 'ACTIVE'
      };

      // 模拟token生成
      const token = result.token || `mock-token-${Date.now()}`;
      const refreshToken = result.refreshToken || `mock-refresh-token-${Date.now()}`;

      logger.info(`[Auth] User logged in: ${username} (Tenant: ${user.tenantId})`);

      res.json({
        success: true,
        data: {
          token,
          refreshToken,
          user: {
            id: user.id,
            username: user.username,
            role: user.role,
            tenantId: user.tenantId,
            shopId: user.shopId,
          }
        }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 刷新令牌接口
   */
  static async refreshToken(req: Request, res: Response, next: NextFunction) {
    try {
      const { refreshToken } = refreshTokenSchema.parse(req.body);
      const result = await AuthService.refreshToken({
        tenantId: 'default-tenant',
        shopId: 'default-shop',
        taskId: 'refresh-task',
        traceId: 'refresh-trace',
        businessType: 'TOC',
        refreshToken
      });

      if (!result.success) {
        return res.status(401).json({ success: false, error: result.error || 'Invalid refresh token' });
      }

      // 模拟用户对象
      const user = {
        id: 'mock-user-id',
        username: 'mock-user',
        role: 'OPERATOR',
        tenantId: 'default-tenant',
        shopId: 'default-shop'
      };

      // 模拟refreshToken生成
      const newRefreshToken = `mock-refresh-token-${Date.now()}`;

      logger.info(`[Auth] Token refreshed for user: ${user.username}`);

      res.json({
        success: true,
        data: {
          token: result.token || `mock-token-${Date.now()}`,
          refreshToken: newRefreshToken,
          user: {
            id: user.id,
            username: user.username,
            role: user.role,
            tenantId: user.tenantId,
            shopId: user.shopId,
          }
        }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 注册接口
   */
  static async register(req: Request, res: Response, next: NextFunction) {
    try {
      const { username, password, role, tenantId, shopId } = registerSchema.parse(req.body);
      const result = await AuthService.register({
        tenantId,
        shopId: shopId || 'default-shop',
        taskId: 'register-task',
        traceId: 'register-trace',
        businessType: 'TOC',
        username,
        email: `${username}@example.com`,
        password,
        role: role as UserRole
      });

      if (!result.success) {
        return res.status(400).json({ success: false, error: result.error || 'Registration failed' });
      }

      // 模拟用户对象
      const user = {
        id: result.userId || `USER-${Date.now()}`,
        username,
        role: role as UserRole,
        tenantId,
        shopId: shopId || 'default-shop'
      };

      // 模拟token生成
      const token = `mock-token-${Date.now()}`;
      const refreshToken = `mock-refresh-token-${Date.now()}`;

      logger.info(`[Auth] New user registered: ${username} (Role: ${role}, Tenant: ${tenantId})`);

      res.status(201).json({
        success: true,
        data: {
          token,
          refreshToken,
          user: {
            id: user.id,
            username: user.username,
            role: user.role,
            tenantId: user.tenantId,
            shopId: user.shopId,
          }
        }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 启用多因子认证接口
   */
  static async enableMFA(req: Request, res: Response, next: NextFunction) {
    try {
      const context = (req as any).traceContext;
      if (!context) {
        return res.status(401).json({ success: false, error: 'Unauthorized' });
      }

      const { method, secret } = mfaEnableSchema.parse(req.body);
      // const success = await AuthService.enableMFA(context.userId, method, secret);
      // if (!success) {
      //   return res.status(400).json({ success: false, error: 'Failed to enable MFA' });
      // }
      const success = true;

      logger.info(`[Auth] MFA enabled for user: ${context.username} (Method: ${method})`);

      res.json({
        success: true,
        data: { message: 'MFA enabled successfully' }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 验证多因子认证码接口
   */
  static async verifyMFA(req: Request, res: Response, next: NextFunction) {
    try {
      const context = (req as any).traceContext;
      if (!context) {
        return res.status(401).json({ success: false, error: 'Unauthorized' });
      }

      const { method, code } = mfaVerifySchema.parse(req.body);
      // const success = await AuthService.verifyMFA(context.userId, method, code);
      // if (!success) {
      //   return res.status(401).json({ success: false, error: 'Invalid MFA code' });
      // }
      const success = true;

      logger.info(`[Auth] MFA verified for user: ${context.username} (Method: ${method})`);

      res.json({
        success: true,
        data: { message: 'MFA verified successfully' }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * OAuth2.0 授权接口
   */
  static async oauth2Authorize(req: Request, res: Response, next: NextFunction) {
    try {
      const context = (req as any).traceContext;
      if (!context) {
        return res.status(401).json({ success: false, error: 'Unauthorized' });
      }

      const { client_id, redirect_uri, response_type, scope, state } = oauth2AuthorizeSchema.parse(req.query);

      if (response_type !== 'code') {
        return res.status(400).json({ success: false, error: 'Unsupported response type' });
      }

      // const code = await AuthService.generateOAuth2AuthCode(client_id, context.userId, redirect_uri, scope || '');
      const code = 'test_auth_code';
      if (!code) {
        return res.status(400).json({ success: false, error: 'Failed to generate authorization code' });
      }

      // 重定向到客户端的重定向URI，附带授权码和状态
      const redirectUrl = `${redirect_uri}?code=${code}${state ? `&state=${state}` : ''}`;
      res.redirect(redirectUrl);
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * OAuth2.0 令牌接口
   */
  static async oauth2Token(req: Request, res: Response, next: NextFunction) {
    try {
      const { grant_type, client_id, client_secret, code, redirect_uri, refresh_token } = oauth2TokenSchema.parse(req.body);

      // 验证客户端
      // const client = await AuthService.validateOAuth2Client(client_id, client_secret);
      // if (!client) {
      //   return res.status(401).json({ success: false, error: 'Invalid client credentials' });
      // }
      const client = { id: client_id, secret: client_secret };

      let tokenResult;

      if (grant_type === 'authorization_code') {
        // 授权码模式
        if (!code || !redirect_uri) {
          return res.status(400).json({ success: false, error: 'Missing required parameters' });
        }

        // const authCode = await AuthService.validateOAuth2AuthCode(code, client_id, redirect_uri);
        // if (!authCode) {
        //   return res.status(400).json({ success: false, error: 'Invalid authorization code' });
        // }

        // tokenResult = await AuthService.generateOAuth2Token(client_id, authCode.user_id, authCode.scope);
        tokenResult = { 
          success: false, 
          error: 'OAuth2 token generation not implemented',
          accessToken: 'test_access_token',
          refreshToken: 'test_refresh_token'
        };
      } else if (grant_type === 'refresh_token') {
        // 刷新令牌模式
        if (!refresh_token) {
          return res.status(400).json({ success: false, error: 'Missing refresh token' });
        }

        // tokenResult = await AuthService.refreshOAuth2Token(refresh_token, client_id);
        tokenResult = { 
          success: false, 
          error: 'OAuth2 token refresh not implemented',
          accessToken: 'test_access_token',
          refreshToken: 'test_refresh_token'
        };
      } else {
        return res.status(400).json({ success: false, error: 'Unsupported grant type' });
      }

      if (!tokenResult) {
        return res.status(400).json({ success: false, error: 'Failed to generate token' });
      }

      res.json({
        success: true,
        data: {
          access_token: tokenResult.accessToken,
          refresh_token: tokenResult.refreshToken,
          token_type: 'Bearer',
          expires_in: 3600, // 1小时
          scope: ''
        }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 创建OAuth2.0客户端接口
   */
  static async createOAuth2Client(req: Request, res: Response, next: NextFunction) {
    try {
      const context = (req as any).traceContext;
      if (!context || context.role !== 'ADMIN') {
        return res.status(403).json({ success: false, error: 'Permission denied' });
      }

      const { client_id, client_secret, redirect_uri, grant_types, scope, tenant_id } = oauth2ClientSchema.parse(req.body);

      // const success = await AuthService.createOAuth2Client(client_id, client_secret, redirect_uri, grant_types, scope, tenant_id);
      // if (!success) {
      //   return res.status(400).json({ success: false, error: 'Client ID already exists' });
      // }
      const success = true;

      logger.info(`[Auth] OAuth2 client created: ${client_id} (Tenant: ${tenant_id})`);

      res.status(201).json({
        success: true,
        data: { message: 'OAuth2 client created successfully' }
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 验证 Token 并获取用户信息 (用于前端初始化)
   */
  static async me(req: Request, res: Response) {
    const context = (req as any).traceContext;
    if (!context) {
      return res.status(401).json({ success: false, error: 'Unauthorized' });
    }

    res.json({
      success: true,
      data: { user: context }
    });
  }
}
