import * as authService from '../services/auth.service.js';
import { verifyRefreshToken, generateAccessToken } from '../utils/jwt.js';
import { getUserById } from '../services/auth.service.js';

/**
 * KROK 1: Login s temporary password
 * POST /api/auth/login
 */
export const login = async (req, res, next) => {
  const { username, password, rememberMe } = req.body;
  const ipAddress = req.ip || req.connection.remoteAddress;
  const userAgent = req.headers['user-agent'];

  try {
    const result = await authService.loginWithTempPassword(
      username,
      password,
      ipAddress,
      userAgent
    );

    // Nastav cookie s access tokenom (httpOnly, secure)
    const isProduction = process.env.NODE_ENV === 'production';
    res.cookie('accessToken', result.tokens.accessToken, {
      httpOnly: true,
      secure: isProduction,
      sameSite: isProduction ? 'strict' : 'lax',
      maxAge: 60 * 60 * 1000, // 1 hodina
    });

    // Refresh token iba ak user chce zostať prihlásený
    if (rememberMe) {
      res.cookie('refreshToken', result.tokens.refreshToken, {
        httpOnly: true,
        secure: isProduction,
        sameSite: isProduction ? 'strict' : 'lax',
        maxAge: 7 * 24 * 60 * 60 * 1000, // 7 dní
      });
    }

    res.status(200).json({
      success: true,
      data: {
        user: result.user,
        tokens: result.tokens,
        needsPasswordChange: result.needsPasswordChange,
        needsEmailSetup: result.needsEmailSetup,
      },
      message: 'Prihlásenie úspešné',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Refresh access token using refresh token
 * POST /api/auth/refresh
 */
export const refreshToken = async (req, res, next) => {
  try {
    const token = req.cookies?.refreshToken;

    if (!token) {
      return res.status(401).json({
        success: false,
        error: {
          message: 'Refresh token nie je k dispozícii',
          statusCode: 401,
        },
      });
    }

    // Verify refresh token
    const decoded = verifyRefreshToken(token);

    // Get user from DB
    const user = await getUserById(decoded.id);

    // Generate new access token
    const newAccessToken = generateAccessToken({
      id: user.id,
      username: user.username,
      role: user.role,
    });

    // Set new access token cookie
    const isProduction = process.env.NODE_ENV === 'production';
    res.cookie('accessToken', newAccessToken, {
      httpOnly: true,
      secure: isProduction,
      sameSite: isProduction ? 'strict' : 'lax',
      maxAge: 60 * 60 * 1000, // 1 hodina
    });

    res.status(200).json({
      success: true,
      data: {
        accessToken: newAccessToken,
      },
      message: 'Token obnovený',
    });
  } catch (error) {
    // Clear invalid cookies
    res.clearCookie('accessToken');
    res.clearCookie('refreshToken');

    return res.status(401).json({
      success: false,
      error: {
        message: 'Refresh token expiroval alebo je neplatný',
        statusCode: 401,
      },
    });
  }
};

/**
 * KROK 2: Nastavenie nového hesla
 * POST /api/auth/set-password
 * Requires: authentication
 */
export const setPassword = async (req, res, next) => {
  const { newPassword } = req.body;
  const userId = req.userId;
  const ipAddress = req.ip || req.connection.remoteAddress;
  const userAgent = req.headers['user-agent'];

  try {
    const result = await authService.setNewPassword(userId, newPassword, { userId, ipAddress, userAgent });

    res.status(200).json({
      success: true,
      data: result,
      message: 'Heslo úspešne nastavené',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * KROK 3: Pripojenie emailu s JMAP validáciou
 * POST /api/auth/link-email
 * Requires: authentication
 */
export const linkEmail = async (req, res, next) => {
  const { email, emailPassword } = req.body;
  const userId = req.userId;
  const ipAddress = req.ip || req.connection.remoteAddress;
  const userAgent = req.headers['user-agent'];

  try {
    const result = await authService.linkEmail(userId, email, emailPassword, { userId, ipAddress, userAgent });

    res.status(200).json({
      success: true,
      data: {
        email,
        accountId: result.accountId,
      },
      message: 'Email účet úspešne pripojený a overený',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * KROK 3 (alternatíva): Skip email setup
 * POST /api/auth/skip-email
 * Requires: authentication
 */
export const skipEmail = async (req, res, next) => {
  const userId = req.userId;

  try {
    const result = await authService.skipEmailSetup(userId);

    res.status(200).json({
      success: true,
      data: result,
      message: 'Email setup preskočený',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Logout
 * POST /api/auth/logout
 * Requires: authentication
 */
export const logout = async (req, res, next) => {
  try {
    const userId = req.userId;
    const ipAddress = req.ip || req.connection.remoteAddress;
    const userAgent = req.headers['user-agent'];

    const result = await authService.logout({ userId, ipAddress, userAgent });

    // Vymaž cookies
    res.clearCookie('accessToken');
    res.clearCookie('refreshToken');

    res.status(200).json({
      success: true,
      message: result.message,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Získanie aktuálnej session info
 * GET /api/auth/session
 * Requires: authentication
 */
export const getSession = async (req, res, next) => {
  try {
    res.status(200).json({
      success: true,
      data: {
        user: req.user,
        authenticated: true,
      },
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Profil aktuálneho usera
 * GET /api/auth/me
 * Requires: authentication
 */
export const getMe = async (req, res, next) => {
  try {
    res.status(200).json({
      success: true,
      data: {
        user: req.user,
      },
    });
  } catch (error) {
    next(error);
  }
};
