const passport = require('passport');
const oauthService = require('../services/OAuthService');

/**
 * OAuth Controller
 * Verwaltet OAuth-Logins
 */
class OAuthController {
  createStateCookie(stateToken) {
    const secure = process.env.NODE_ENV === 'production' ? '; Secure' : '';
    return `timeclock_oauth_state=${encodeURIComponent(stateToken)}; Max-Age=900; Path=/api/auth/google/callback; HttpOnly; SameSite=Lax${secure}`;
  }

  clearStateCookie() {
    const secure = process.env.NODE_ENV === 'production' ? '; Secure' : '';
    return `timeclock_oauth_state=; Max-Age=0; Path=/api/auth/google/callback; HttpOnly; SameSite=Lax${secure}`;
  }

  readStateCookie(req) {
    const cookieHeader = req.headers.cookie || '';
    const cookie = cookieHeader
      .split(';')
      .map(part => part.trim())
      .find(part => part.startsWith('timeclock_oauth_state='));

    return cookie ? decodeURIComponent(cookie.slice('timeclock_oauth_state='.length)) : null;
  }

  /**
   * Google OAuth initiieren
   * GET /api/auth/google
   */
  googleAuth(req, res, next) {
    const state = req.query.stateToken || oauthService.createStateToken({
      platform: req.query.platform === 'android' ? 'android' : 'web'
    });

    const clientId = process.env.GOOGLE_CLIENT_ID;
    const callbackUrl = process.env.GOOGLE_CALLBACK_URL || 'http://localhost:3010/api/auth/google/callback';

    if (!clientId) {
      return res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:5010'}/login?error=oauth_not_configured`);
    }

    const params = new URLSearchParams({
      response_type: 'code',
      client_id: clientId,
      redirect_uri: callbackUrl,
      scope: 'profile email',
      state
    });

    res.setHeader('Set-Cookie', this.createStateCookie(state));
    return res.redirect(`https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`);
  }

  /**
   * Google OAuth-Verknüpfung für eingeloggte Benutzer starten
   * POST /api/auth/google/link-url
   */
  createGoogleLinkUrl(req, res) {
    try {
      const platform = req.body?.platform === 'android' ? 'android' : 'web';
      const stateToken = oauthService.createStateToken({
        mode: 'link',
        platform,
        userId: req.user.userId
      });
      const baseUrl = process.env.API_PUBLIC_URL || `${req.protocol}://${req.get('host')}/api`;
      res.json({
        success: true,
        url: `${baseUrl}/auth/google?stateToken=${encodeURIComponent(stateToken)}`
      });
    } catch (error) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  /**
   * Google OAuth Callback
   * GET /api/auth/google/callback
   */
  googleCallback(req, res, next) {
    passport.authenticate('google', { 
      session: false,
      failureRedirect: `${process.env.FRONTEND_URL || 'http://localhost:5010'}/login?error=oauth_failed`
    }, async (err, result) => {
      if (err || !result) {
        console.error('Google OAuth Fehler:', err);
        return res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:5010'}/login?error=oauth_failed`);
      }

      try {
        const stateToken = req.query.state || this.readStateCookie(req);
        const state = oauthService.verifyStateToken(stateToken);
        const authResult = await oauthService.completeOAuthLogin(result.profile, result.provider, {
          linkUserId: state.mode === 'link' ? state.userId : null
        });

        const target = state.platform === 'android'
          ? 'timeclock://oauth-callback'
          : `${process.env.FRONTEND_URL || 'http://localhost:5010'}/oauth-callback`;

        if (authResult.requiresLink) {
          const params = new URLSearchParams({
            pending: authResult.pendingToken,
            email: authResult.email || '',
            provider: result.provider
          });
          res.setHeader('Set-Cookie', this.clearStateCookie());
          return res.redirect(`${target}?${params.toString()}`);
        }

        const params = new URLSearchParams({
          token: authResult.token
        });
        if (state.mode === 'link') {
          params.set('linked', result.provider);
        }

        res.setHeader('Set-Cookie', this.clearStateCookie());
        return res.redirect(`${target}?${params.toString()}`);
      } catch (callbackError) {
        console.error('Google OAuth Callback-Verarbeitung fehlgeschlagen:', callbackError);
        res.setHeader('Set-Cookie', this.clearStateCookie());
        return res.redirect(`${process.env.FRONTEND_URL || 'http://localhost:5010'}/login?error=oauth_failed`);
      }
    })(req, res, next);
  }

  async linkExistingAccount(req, res) {
    try {
      const { pendingToken, email, password } = req.body;
      if (!pendingToken || !email || !password) {
        return res.status(400).json({ success: false, error: 'pendingToken, E-Mail und Passwort sind erforderlich' });
      }
      const result = await oauthService.linkPendingToPasswordAccount(pendingToken, email, password);
      res.json({ success: true, token: result.token, user: result.user });
    } catch (error) {
      console.error('OAuth-Verknüpfung mit bestehendem Account fehlgeschlagen:', error);
      res.status(401).json({ success: false, error: error.message });
    }
  }

  async linkPendingToCurrentUser(req, res) {
    try {
      const { pendingToken } = req.body;
      if (!pendingToken) {
        return res.status(400).json({ success: false, error: 'pendingToken ist erforderlich' });
      }
      const result = await oauthService.linkPendingToAuthenticatedUser(pendingToken, req.user.userId);
      res.json({ success: true, token: result.token, user: result.user });
    } catch (error) {
      console.error('OAuth-Verknüpfung fehlgeschlagen:', error);
      res.status(400).json({ success: false, error: error.message });
    }
  }

  /**
   * OAuth-Identities für Benutzer abrufen
   * GET /api/auth/identities
   */
  async getIdentities(req, res) {
    try {
      const userId = req.user.userId;
      const identities = await oauthService.getUserIdentities(userId);

      res.json({
        success: true,
        identities
      });
    } catch (error) {
      console.error('Fehler beim Abrufen der Identities:', error);
      
      res.status(500).json({
        success: false,
        error: 'Fehler beim Abrufen der OAuth-Verknüpfungen'
      });
    }
  }

  /**
   * OAuth-Provider entfernen
   * DELETE /api/auth/identity/:provider
   */
  async unlinkProvider(req, res) {
    try {
      const userId = req.user.userId;
      const { provider } = req.params;
      const unlinked = await oauthService.unlinkProvider(userId, provider);

      if (unlinked) {
        res.json({
          success: true,
          message: `${provider} wurde erfolgreich entfernt`
        });
      } else {
        res.status(404).json({
          success: false,
          error: 'Verknüpfung nicht gefunden'
        });
      }
    } catch (error) {
      console.error('Fehler beim Entfernen der Identity:', error);
      
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  }
}

module.exports = new OAuthController();
