const Admin = require('../models/admin')
const boom = require("boom");
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')


const fastify = require("fastify");
const { Tank, MotorData, IotData } = require('../models/tanks')
const JWT_SECRET = 'your-secret-key';

async function generateCustomerId(role) {
  let customerId;
  let isUnique = false;
  let prefix;

  // Set the prefix based on the role
  switch (role) {
    case 'admin':
      prefix = 'AWSAD';
      break;
    case 'sales':
      prefix = 'AWSSL';
      break;
    case 'store':
      prefix = 'AWSST';
      break;
    default:
      throw new Error('Invalid role for customer ID generation');
  }

  while (!isUnique) {
    // Generate a random number or string for the customer ID
    const randomId = Math.floor(1000 + Math.random() * 9000).toString(); // Generates a random number between 1000 and 9999
    customerId = `${prefix}${randomId}`;
    // Check for uniqueness in the Admin collection
    const existingAdmin = await Admin.findOne({ customerId });
    if (!existingAdmin) {
      isUnique = true; // Exit the loop if the customer ID is unique
    }
  }

  return customerId;
}


exports.adminSignUp = async (request, reply) => {
  try {
    const { phone, username, password, role } = request.body;

    if (!username || username.trim() === '') {
      return reply.status(400).send({ message: 'Username is required' });
    }

    // Validate role
    if (!role || !['admin', 'sales', 'store'].includes(role)) {
      return reply.status(400).send({ message: 'Invalid role. Must be either admin, sales, or store' });
    }

  

    // Check if an admin with the same phone number or username already exists
    // const existingAdminUsername = await Admin.findOne({ username });
    // const existingAdmin = await Admin.findOne({ phone });

    // if (existingAdmin) {
    //   return reply.status(400).send({ message: 'Phone already registered' });
    // }
    // if (existingAdminUsername) {
    //   return reply.status(400).send({ message: 'Username already registered' });
    // }

    // Hash the password using bcrypt
    const hashedPassword = await bcrypt.hash(password, 10);

    const customerId = await generateCustomerId(role); // Assuming you have this function defined elsewhere
    //const building = 'ADMIN'; // You can customize this logic to derive from a parameter or a default value
    //const customerId = `AWSU${building}${c_id}`; // Construct the customer ID

    // Create a new admin object with the hashed password and role
    const admin = new Admin({ phone, username, password: hashedPassword, customerId, role });

    // Save the new admin to the database
    await admin.save();

    reply.send({ message: 'Admin Account Created Successfully' });
  } catch (err) {
    reply.status(500).send({ message: err.message });
  }
};


// Admin Login Function (With Phone Number)
// exports.adminLogin = async (request, reply) => {
//   try {
//     const { phone, password } = request.body;

//     // Check if an admin with the phone number exists
//     const admin = await Admin.findOne({ phone });

//     if (!admin) {
//       return reply.status(401).send({ message: 'Invalid phone number or password' });
//     }

//     // Compare the password entered by the user with the hashed password stored in the database
//     const isPasswordValid = await bcrypt.compare(password, admin.password);

//     if (!isPasswordValid) {
//       return reply.status(401).send({ message: 'Invalid phone number or password' });
//     }

    
//     // Generate a JWT token for the authenticated admin
//     const token = jwt.sign({ phone: admin.phone, role: 'admin' }, JWT_SECRET, { expiresIn: '1h' });

//     return reply.send({ token, admin });
//   } catch (err) {
//     reply.status(500).send({ message: err.message });
//   }
// };

exports.adminLogin = async (request, reply) => {
  try {
    const { phone, password } = request.body;

    // Check if an admin with the phone number exists
    const admin = await Admin.findOne({ phone });

    if (!admin) {
      return reply.status(401).send({
        simplydata: {
          error: true,
          message: "Invalid phone number or password",
        },
      });
    }

    // Compare the password entered by the user with the hashed password stored in the database
    const isPasswordValid = await bcrypt.compare(password, admin.password);

    if (!isPasswordValid) {
      return reply.status(401).send({
        simplydata: {
          error: true,
          message: "Invalid phone number or password",
        },
      });
    }

    // Generate a JWT token for the authenticated admin
    const token = jwt.sign(
      { phone: admin.phone, role: admin.role },
      JWT_SECRET,
      { expiresIn: "1h" }
    );

    // Create the response payload
    const responsePayload = {
      simplydata: {
        error: false,
        apiversion: process.env.APIVERSION,
        access_token: token,
        phone: admin.phone,
        type: admin.role,
        customerId: admin.customerId || null,
        username: admin.username || null,
      },
    };

    // Send the response
    return reply.send(responsePayload);
  } catch (err) {
    reply.status(500).send({
      simplydata: {
        error: true,
        message: err.message,
      },
    });
  }
};


// adminController.js

exports.editUserByCustomerId = async (req, reply) => {
  const { customerId } = req.params;
  const { phone, username, role, date } = req.body;

  try {
    const updatedUser = await Admin.findOneAndUpdate(
      { customerId: customerId },   
      { phone, username, role, date },  
    );

    if (!updatedUser) {
      return reply.status(404).send({ success: false, message: "User not found" });
    }

    return reply.send({ success: true, message: "User details updated successfully", data: updatedUser });
  } catch (error) {
    return reply.status(500).send({ success: false, message: error.message });
  }
};

exports.deleteUserInfo = async (req, reply) => {
  try {
    const customerId = req.params.customerId;
   
    const tank = await Admin.findOneAndDelete({ customerId:customerId });

    reply.send({ status_code: 200, message: 'Delete Sucessfully'});
   // return tank;
  } catch (err) {
    throw boom.boomify(err);
  }
};



exports.salesStoreLogin = async (request, reply) => {
  try {
    const { phone, password, role } = request.body;

    // Check if a user (sales or store) with the phone number and role exists
    const user = await Admin.findOne({ phone, role });

    if (!user) {
      return reply.status(401).send({ message: 'Invalid phone number, password, or role' });
    }

    // Compare the password entered by the user with the hashed password stored in the database
    const isPasswordValid = await bcrypt.compare(password, user.password);

    if (!isPasswordValid) {
      return reply.status(401).send({ message: 'Invalid phone number, password, or role' });
    }

    // Generate a JWT token for the authenticated user (with role sales or store)
    const token = jwt.sign({ phone: user.phone, role: user.role }, JWT_SECRET, { expiresIn: '1h' });

    return reply.send({ token });
  } catch (err) {
    reply.status(500).send({ message: err.message });
  }
};


exports.getUsersByRole = async (request, reply) => {
  try {
    const { role } = request.params;

    // Ensure the role is either 'sales' or 'store'
    if (!['sales', 'store'].includes(role)) {
      return reply.status(400).send({ message: 'Invalid role. Must be either sales or store.' });
    }

    // Find users with the specific role (sales or store)
    const users = await Admin.find({ role });

    // Send back the list of users
    reply.send(users);
  } catch (err) {
    reply.status(500).send({ message: err.message });
  }
};

exports.getUserByCustomerId = async (request, reply) => {
  try {
    const { customerId } = request.params;

    // Check if customerId is provided
    if (!customerId) {
      return reply.status(400).send({ message: 'Customer ID is required' });
    }

    // Fetch the user from the database
    const user = await Admin.findOne({ customerId });

    // If user not found, return a 404 response
    if (!user) {
      return reply.status(404).send({ message: 'User not found' });
    }

    // Return the user data
    return reply.send(user);
  } catch (err) {
    return reply.status(500).send({ message: err.message });
  }
};




exports.createUser = async (request, reply) => {
  const { phone, password, role } = request.body;

  // Validate role (only sales or store)
  if (!['sales', 'store'].includes(role)) {
    return reply.status(400).send({ message: 'Invalid role. Must be either sales or store' });
  }

  try {
    const existingUser = await Admin.findOne({ phone });

    if (existingUser) {
      return reply.status(400).send({ message: 'User with this phone number already exists' });
    }

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

    // Create the new user
    const newUser = new Admin({
      phone,
      password: hashedPassword,
      role,
    });

    await newUser.save();
    return reply.send({ message: 'User created successfully' });
  } catch (err) {
    reply.status(500).send({ message: err.message });
  }
};




  exports.integratingHardwareidToTank =  async (request, reply) => {
    try {
        const { customerId, tankName,tankLocation,hardwareId,hardwareId_company,hardwareId_type } = request.body
       const tank =  await Tank.findOneAndUpdate({customerId, tankName:tankName ,tankLocation:tankLocation.toLowerCase()}, { $set: { hardwareId: hardwareId,hardwareId_company:hardwareId_company,hardwareId_type:hardwareId_type } });
        reply.send({ status_code: 200, message:`${hardwareId} set to ${tankName}` }); 

      } catch (err) {
        reply.status(500).send({ message: err.message })
      }
  }

