"use strict";

/**
 * Authentication Methods Mixin
 */

import { OxyAuthenticationError } from '../OxyServices.errors';
export function OxyServicesAuthMixin(Base) {
  return class extends Base {
    constructor(...args) {
      super(...args);
    }
    /**
     * Sign up a new user
     */
    async signUp(username, email, password) {
      try {
        const res = await this.makeRequest('POST', '/api/auth/signup', {
          username,
          email,
          password
        }, {
          cache: false
        });
        if (!res || typeof res === 'object' && Object.keys(res).length === 0) {
          throw new OxyAuthenticationError('Sign up failed', 'SIGNUP_FAILED', 400);
        }
        return res;
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Request account recovery (send verification code)
     */
    async requestRecovery(identifier) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/request', {
          identifier
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Verify recovery code
     */
    async verifyRecoveryCode(identifier, code) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/verify', {
          identifier,
          code
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Reset password using verified code
     */
    async resetPassword(identifier, code, newPassword) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/reset', {
          identifier,
          code,
          newPassword
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Reset password using TOTP code (recommended recovery)
     */
    async resetPasswordWithTotp(identifier, code, newPassword) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/totp/reset', {
          identifier,
          code,
          newPassword
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }
    async resetPasswordWithBackupCode(identifier, backupCode, newPassword) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/backup/reset', {
          identifier,
          backupCode,
          newPassword
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }
    async resetPasswordWithRecoveryKey(identifier, recoveryKey, newPassword) {
      try {
        return await this.makeRequest('POST', '/api/auth/recover/recovery-key/reset', {
          identifier,
          recoveryKey,
          newPassword
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Sign in with device management
     */
    async signIn(username, password, deviceName, deviceFingerprint) {
      try {
        return await this.makeRequest('POST', '/api/auth/login', {
          username,
          password,
          deviceName,
          deviceFingerprint
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Complete login by verifying TOTP with MFA token
     */
    async verifyTotpLogin(mfaToken, code) {
      try {
        return await this.makeRequest('POST', '/api/auth/totp/verify-login', {
          mfaToken,
          code
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get user by session ID
     */
    async getUserBySession(sessionId) {
      try {
        return await this.makeRequest('GET', `/api/session/user/${sessionId}`, undefined, {
          cache: true,
          cacheTTL: 2 * 60 * 1000 // 2 minutes cache for user data
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Batch get multiple user profiles by session IDs (optimized for account switching)
     * Returns array of { sessionId, user } objects
     */
    async getUsersBySessions(sessionIds) {
      try {
        if (!Array.isArray(sessionIds) || sessionIds.length === 0) {
          return [];
        }

        // Deduplicate and sort sessionIds for consistent cache keys
        const uniqueSessionIds = Array.from(new Set(sessionIds)).sort();
        return await this.makeRequest('POST', '/api/session/users/batch', {
          sessionIds: uniqueSessionIds
        }, {
          cache: true,
          cacheTTL: 2 * 60 * 1000,
          // 2 minutes cache
          deduplicate: true // Important for batch requests
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get access token by session ID and set it in the token store
     */
    async getTokenBySession(sessionId) {
      try {
        const res = await this.makeRequest('GET', `/api/session/token/${sessionId}`, undefined, {
          cache: false,
          retry: false
        });

        // Set the token in the centralized token store
        this.setTokens(res.accessToken);
        return res;
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get sessions by session ID
     */
    async getSessionsBySessionId(sessionId) {
      try {
        return await this.makeRequest('GET', `/api/session/sessions/${sessionId}`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Logout from a specific session
     */
    async logoutSession(sessionId, targetSessionId) {
      try {
        const url = targetSessionId ? `/api/session/logout/${sessionId}/${targetSessionId}` : `/api/session/logout/${sessionId}`;
        await this.makeRequest('POST', url, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Logout from all sessions
     */
    async logoutAllSessions(sessionId) {
      try {
        await this.makeRequest('POST', `/api/session/logout-all/${sessionId}`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Validate session
     */
    async validateSession(sessionId, options = {}) {
      try {
        const urlParams = {};
        if (options.deviceFingerprint) urlParams.deviceFingerprint = options.deviceFingerprint;
        if (options.useHeaderValidation) urlParams.useHeaderValidation = 'true';
        return await this.makeRequest('GET', `/api/session/validate/${sessionId}`, urlParams, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Check username availability
     */
    async checkUsernameAvailability(username) {
      try {
        return await this.makeRequest('GET', `/api/auth/check-username/${username}`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Check email availability
     */
    async checkEmailAvailability(email) {
      try {
        return await this.makeRequest('GET', `/api/auth/check-email/${email}`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }
  };
}
//# sourceMappingURL=OxyServices.auth.js.map