import axios from 'axios';
import { UserService } from '../users/user.service';
import { AuthService } from '../auth/auth.service';
import { FileService } from '../files/file.service';
import { UserEntity as User } from '../users/user.entity';
import debug from 'debug';

const logger = {
  info: debug('backend:wechat:info'),
  error: debug('backend:wechat:error')
};

export class WechatAuthService {
  private readonly appId: string = process.env.WECHAT_MP_APP_ID || '';
  private readonly appSecret: string = process.env.WECHAT_MP_APP_SECRET || '';

  constructor(
    private readonly userService: UserService,
    private readonly authService: AuthService,
    private readonly fileService: FileService
  ) {}

  // 获取授权URL
  getAuthorizationUrl(redirectUri: string, scope: 'snsapi_base' | 'snsapi_userinfo' = 'snsapi_userinfo'): string {
    const state = Math.random().toString(36).substring(2);
    return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
  }

  // 通过code获取access_token
  async getAccessToken(code: string): Promise<any> {
    const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`;
    const response = await axios.get(url);
    return response.data;
  }

  // 获取用户信息
  async getUserInfo(accessToken: string, openid: string): Promise<any> {
    const url = `https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openid}&lang=zh_CN`;
    const response = await axios.get(url);
    return response.data;
  }

  // 微信登录/注册
  async wechatLogin(code: string): Promise<{ token: string; user: User }> {
    try {
      // 1. 获取access_token
      const tokenData = await this.getAccessToken(code);
      if (tokenData.errcode) {
        throw new Error(`微信认证失败: ${tokenData.errmsg}`);
      }

      const { access_token, openid, unionid } = tokenData;

      // 2. 检查用户是否存在
      let user = await this.userService.getUserByWechatOpenid(openid);

      if (!user) {
        // 3. 获取用户信息（首次登录）
        const userInfo = await this.getUserInfo(access_token, openid);
        
        // 4. 先创建用户
        user = await this.userService.createUser({
          username: `wx_${openid.substring(0, 8)}`,
          password: Math.random().toString(36).substring(2),
          wechatOpenid: openid,
          wechatUnionid: unionid,
          wechatNickname: userInfo.nickname,
          wechatAvatar: userInfo.headimgurl,
          wechatSex: userInfo.sex,
          wechatProvince: userInfo.province,
          wechatCity: userInfo.city,
          wechatCountry: userInfo.country,
          nickname: userInfo.nickname
        });

        // 5. 下载微信头像并保存到MinIO
        if (userInfo.headimgurl) {
          try {
            const avatarResult = await this.fileService.downloadAndSaveFromUrl(
              userInfo.headimgurl,
              {
                uploadUserId: user.id, // 使用新创建的用户ID
                customPath: 'avatars/wechat/',
                mimeType: 'image/jpeg'
              }
            );
            
            // 更新用户的 avatarFileId
            await this.userService.updateUser(user.id, {
              avatarFileId: avatarResult.file.id
            });
            
            // 更新返回的用户对象
            user.avatarFileId = avatarResult.file.id;
          } catch (error) {
            logger.error('下载微信头像失败:', error);
            // 头像下载失败不影响主要流程
          }
        }
      } else {
        // 已有用户：如果avatarFileId为空，也下载微信头像
        if (!user.avatarFileId) {
          try {
            // 获取最新的用户信息
            const userInfo = await this.getUserInfo(access_token, openid);
            
            if (userInfo.headimgurl) {
              const avatarResult = await this.fileService.downloadAndSaveFromUrl(
                userInfo.headimgurl,
                {
                  uploadUserId: user.id,
                  customPath: 'avatars/wechat/',
                  mimeType: 'image/jpeg'
                }
              );
              
              // 更新用户的 avatarFileId
              await this.userService.updateUser(user.id, {
                avatarFileId: avatarResult.file.id
              });
              
              // 更新返回的用户对象
              user.avatarFileId = avatarResult.file.id;
            }
          } catch (error) {
            logger.error('为已有用户下载微信头像失败:', error);
            // 头像下载失败不影响主要流程
          }
        }
      }

      // 5. 生成JWT token
      const token = this.authService.generateToken(user);
      
      return { token, user };
    } catch (error) {
      logger.error('微信登录失败:', error);
      throw new Error(`微信登录失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  // 绑定微信账号到现有用户
  async bindWechatToUser(userId: number, code: string): Promise<User> {
    try {
      // 1. 获取access_token
      const tokenData = await this.getAccessToken(code);
      if (tokenData.errcode) {
        throw new Error(`微信认证失败: ${tokenData.errmsg}`);
      }

      const { openid, unionid } = tokenData;

      // 2. 检查微信账号是否已被绑定
      const existingUser = await this.userService.getUserByWechatOpenid(openid);
      if (existingUser && existingUser.id !== userId) {
        throw new Error('该微信账号已被其他用户绑定');
      }

      // 3. 获取用户信息
      const userInfo = await this.getUserInfo(tokenData.access_token, openid);

      // 4. 下载微信头像并保存到MinIO
      let avatarFileId: number | null = null;
      if (userInfo.headimgurl) {
        try {
          const avatarResult = await this.fileService.downloadAndSaveFromUrl(
            userInfo.headimgurl,
            {
              uploadUserId: userId,
              customPath: 'avatars/wechat/',
              mimeType: 'image/jpeg'
            }
          );
          avatarFileId = avatarResult.file.id;
        } catch (error) {
          logger.error('下载微信头像失败:', error);
          // 头像下载失败不影响主要流程，继续更新用户
        }
      }

      // 5. 更新用户信息
      const user = await this.userService.updateUser(userId, {
        wechatOpenid: openid,
        wechatUnionid: unionid,
        wechatNickname: userInfo.nickname,
        wechatAvatar: userInfo.headimgurl,
        wechatSex: userInfo.sex,
        wechatProvince: userInfo.province,
        wechatCity: userInfo.city,
        wechatCountry: userInfo.country,
        avatarFileId: avatarFileId
      });

      if (!user) {
        throw new Error('用户不存在');
      }

      return user;
    } catch (error) {
      logger.error('绑定微信账号失败:', error);
      throw new Error(`绑定微信账号失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  // 解绑微信账号
  async unbindWechatFromUser(userId: number): Promise<User> {
    try {
      const user = await this.userService.updateUser(userId, {
        wechatOpenid: null,
        wechatUnionid: null,
        wechatNickname: null,
        wechatAvatar: null,
        wechatSex: null,
        wechatProvince: null,
        wechatCity: null,
        wechatCountry: null
      });

      if (!user) {
        throw new Error('用户不存在');
      }

      return user;
    } catch (error) {
      logger.error('解绑微信账号失败:', error);
      throw new Error(`解绑微信账号失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }
}