const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const db = require('../config/database');

const generateToken = (user) => {
  return jwt.sign(
    { id: user.id, username: user.username, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: '24h' } // Access token: 24 saat
  );
};

const generateRefreshToken = () => {
  return crypto.randomBytes(64).toString('hex');
};

const saveRefreshToken = async (userId, refreshToken) => {
  const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 gün
  await db.query(
    'INSERT INTO refresh_tokens (user_id, token, expires_at) VALUES (?, ?, ?)',
    [userId, refreshToken, expiresAt]
  );
  return expiresAt;
};

exports.register = async (req, res) => {
  try {
    const { username, email, password, role } = req.body;

    const [existingUser] = await db.query(
      'SELECT * FROM users WHERE email = ? OR username = ?',
      [email, username]
    );

    if (existingUser.length > 0) {
      return res.status(400).json({ message: 'Kullanıcı zaten mevcut' });
    }

    const hashedPassword = await bcrypt.hash(password, 10);

    const [result] = await db.query(
      'INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, ?)',
      [username, email, hashedPassword, role || 'admin']
    );

    const token = generateToken({ id: result.insertId, username, role: role || 'admin' });

    res.status(201).json({
      message: 'Kullanıcı başarıyla oluşturuldu',
      token,
      user: { id: result.insertId, username, email, role: role || 'admin' }
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    const [users] = await db.query('SELECT * FROM users WHERE email = ?', [email]);

    if (users.length === 0) {
      return res.status(401).json({ message: 'Geçersiz email veya şifre' });
    }

    const user = users[0];
    const isPasswordValid = await bcrypt.compare(password, user.password);

    if (!isPasswordValid) {
      return res.status(401).json({ message: 'Geçersiz email veya şifre' });
    }

    // Access token oluştur
    const token = generateToken(user);

    // Refresh token oluştur ve veritabanına kaydet
    const refreshToken = generateRefreshToken();
    await saveRefreshToken(user.id, refreshToken);

    // Refresh token'ı secure, httpOnly cookie olarak ayarla
    res.cookie('refreshToken', refreshToken, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production', // Production'da HTTPS gerekli
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000 // 7 gün
    });

    res.json({
      message: 'Giriş başarılı',
      token,
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role
      }
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

exports.getProfile = async (req, res) => {
  try {
    const [users] = await db.query(
      'SELECT id, username, email, role, created_at FROM users WHERE id = ?',
      [req.user.id]
    );

    if (users.length === 0) {
      return res.status(404).json({ message: 'Kullanıcı bulunamadı' });
    }

    res.json(users[0]);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

// Refresh Token endpoint
exports.refreshToken = async (req, res) => {
  try {
    const { refreshToken } = req.cookies;

    if (!refreshToken) {
      return res.status(401).json({ message: 'Refresh token bulunamadı' });
    }

    // Refresh token'ı veritabanında kontrol et
    const [tokens] = await db.query(
      'SELECT rt.*, u.id, u.username, u.role FROM refresh_tokens rt JOIN users u ON rt.user_id = u.id WHERE rt.token = ? AND rt.expires_at > NOW()',
      [refreshToken]
    );

    if (tokens.length === 0) {
      res.clearCookie('refreshToken');
      return res.status(401).json({ message: 'Geçersiz veya süresi dolmuş refresh token' });
    }

    const tokenData = tokens[0];

    // Yeni access token oluştur
    const newAccessToken = generateToken({
      id: tokenData.id,
      username: tokenData.username,
      role: tokenData.role
    });

    res.json({
      token: newAccessToken,
      user: {
        id: tokenData.id,
        username: tokenData.username,
        role: tokenData.role
      }
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

// Logout endpoint
exports.logout = async (req, res) => {
  try {
    const { refreshToken } = req.cookies;

    if (refreshToken) {
      // Refresh token'ı veritabanından sil
      await db.query('DELETE FROM refresh_tokens WHERE token = ?', [refreshToken]);
    }

    // Cookie'yi temizle
    res.clearCookie('refreshToken');

    res.json({ message: 'Çıkış başarılı' });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};
