const Admin = require('../models/Admin');
const { hashPassword, comparePassword } = require('../utils/passwordUtils');
const { generateAccessToken, generateRefreshToken, verifyRefreshToken } = require('../utils/tokenUtils');

const adminController = {
  /**
   * Register new admin
   * POST /api/admin/register
   */
  register: async (req, res) => {
    try {
      const { name, email, password, confirmPassword } = req.body;

      // Validate input
      if (!name || !email || !password || !confirmPassword) {
        return res.status(400).json({
          status: false,
          message: 'All fields are required',
          data: null,
        });
      }

      // Validate email format
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        return res.status(400).json({
          status: false,
          message: 'Invalid email format',
          data: null,
        });
      }

      // Validate password strength
      if (password.length < 6) {
        return res.status(400).json({
          status: false,
          message: 'Password must be at least 6 characters long',
          data: null,
        });
      }

      // Check password match
      if (password !== confirmPassword) {
        return res.status(400).json({
          status: false,
          message: 'Passwords do not match',
          data: null,
        });
      }

      // Check if admin already exists
      const existingAdmin = await Admin.findByEmail(email);
      if (existingAdmin) {
        return res.status(409).json({
          status: false,
          message: 'Email already registered',
          data: null,
        });
      }

      // Hash password
      const hashedPassword = await hashPassword(password);

      // Create admin
      const adminId = await Admin.create(name, email, hashedPassword, 'admin');

      return res.status(201).json({
        status: true,
        message: 'Admin registered successfully',
        data: {
          id: adminId,
          name,
          email,
          role: 'admin',
        },
      });
    } catch (error) {
      console.error('Register error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Login admin
   * POST /api/admin/login
   */
  login: async (req, res) => {
    try {
      const { email, password } = req.body;

      // Validate input
      if (!email || !password) {
        return res.status(400).json({
          status: false,
          message: 'Email and password are required',
          data: null,
        });
      }

      // Find admin by email
      const admin = await Admin.findByEmail(email);
      if (!admin) {
        return res.status(401).json({
          status: false,
          message: 'Invalid email or password',
          data: null,
        });
      }

      // Compare password
      const isPasswordValid = await comparePassword(password, admin.password);
      if (!isPasswordValid) {
        return res.status(401).json({
          status: false,
          message: 'Invalid email or passwordss',
          data: null,
        });
      }

      // Generate tokens
      const accessToken = generateAccessToken(admin.id, admin.email, admin.role);
      const refreshToken = generateRefreshToken(admin.id);

      // Store refresh token in database
      await Admin.updateRefreshToken(admin.id, refreshToken);

      // Set refresh token as HTTP-only cookie
      res.cookie('refreshToken', refreshToken, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
      });

      return res.status(200).json({
        status: true,
        message: 'Login successful',
        data: {
          id: admin.id,
          name: admin.name,
          email: admin.email,
          role: admin.role,
          accessToken,
          refreshToken,
        },
      });
    } catch (error) {
      console.error('Login error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Refresh access token
   * POST /api/admin/refresh
   */
  refresh: async (req, res) => {
    try {
      // Get refresh token from cookie or body
      const refreshToken = req.cookies.refreshToken || req.body.refreshToken;

      if (!refreshToken) {
        return res.status(401).json({
          status: false,
          message: 'Refresh token is required',
          data: null,
        });
      }

      // Verify refresh token
      const decoded = verifyRefreshToken(refreshToken);
      if (!decoded) {
        return res.status(401).json({
          status: false,
          message: 'Invalid or expired refresh token',
          data: null,
        });
      }

      // Get admin info
      const admin = await Admin.findById(decoded.id);
      if (!admin || admin.refresh_token !== refreshToken) {
        return res.status(401).json({
          status: false,
          message: 'Refresh token mismatch',
          data: null,
        });
      }

      // Generate new access token
      const newAccessToken = generateAccessToken(admin.id, admin.email, admin.role);

      return res.status(200).json({
        status: true,
        message: 'Token refreshed successfully',
        data: {
          accessToken: newAccessToken,
        },
      });
    } catch (error) {
      console.error('Refresh error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Logout admin
   * POST /api/admin/logout
   */
  logout: async (req, res) => {
    try {
      const adminId = req.admin.id;

      // Clear refresh token from database
      await Admin.clearRefreshToken(adminId);

      // Clear cookie
      res.clearCookie('refreshToken', {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
      });

      return res.status(200).json({
        status: true,
        message: 'Logout successful',
        data: null,
      });
    } catch (error) {
      console.error('Logout error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Get all admins
   * GET /api/admin
   */
  getAll: async (req, res) => {
    try {
      const admins = await Admin.getAll();
      return res.status(200).json({
        status: true,
        message: 'Admins retrieved successfully',
        data: admins,
      });
    } catch (error) {
      console.error('Get all admins error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },
};

module.exports = adminController;
