const { deleteFile } = require('../../helpers');
const { deleteFilesFromFileServer } = require('../../util/file-handlers');
const { Drivers } = require('../../models');
const { errorHandler } = require('../../util');
const { formatCase, formatImage } = require('../../util/formatter');
const passport = require('../../util/passport/members/member-passport-config');
const jwt = require('jsonwebtoken');

exports.driverAccountCreate = (req, res, next) => {
	passport.authenticate('signup-driver', { session: false }, async (err, driver, info) => {
		try {
			if (err) {
				return next(err);
			}

			if (!driver) {
				return res.status(400).json({ success: false, message: info.message || 'Registration failed' });
			}

			const token = jwt.sign({ driverId: driver.id, userType: 'Driver' }, process.env.DRIVER_SECRET_KEY, {
				expiresIn: '2h',
			});

			return res.status(201).json({
				success: true,
				token,
			});
		} catch (error) {
			return next(error);
		}
	})(req, res, next);
};

// exports.createDriver = async (req, res, next) => {
// 	try {
// 		const {
// 			email_address,
// 			password,
// 			conductor_name,
// 			shuttle_number,
// 			plate_number,
// 			first_name,
// 			middle_name,
// 			last_name,
// 			phone_no,
// 		} = formatCase(req.body, 'snake');

// 		const existingUser = await Drivers.findOne({ where: { email_address } });
// 		if (existingUser) {
// 			return errorHandler('Email already in use.', 409);
// 		}

// 		const { driver_photo, vehicle_photo } = req.files;

// 		let newUser = await Drivers.create({
// 			email_address,
// 			password,
// 			first_name,
// 			middle_name,
// 			last_name,
// 			phone_no,
// 			conductor_name,
// 			shuttle_number,
// 			plate_number,
// 			driver_photo: driver_photo[0].filename,
// 			vehicle_photo: vehicle_photo[0].filename,
// 		});

// 		newUser = newUser.get({ plain: true });
// 		delete newUser.password;

// 		res.status(201).json({ success: true, data: formatCase(newUser) });
// 	} catch (error) {
// 		next(error);
// 	}
// };

exports.driverLogin = (req, res, next) => {
	passport.authenticate('login-driver', (err, driver, info) => {
		if (err) {
			return next(err);
		}
		if (!driver) {
			return res.status(400).json({ success: false, message: info.message });
		}

		const token = jwt.sign({ driverId: driver.id, userType: 'Driver' }, process.env.DRIVER_SECRET_KEY, {
			expiresIn: '2h',
		});

		res.json({ success: true, token });
	})(req, res, next);
};

exports.getProfile = async (req, res, next) => {
	try {
		const { driverId } = req;

		let driver = await Drivers.findOne({
			where: {
				id: driverId,
			},
			attributes: {
				exclude: ['password'],
			},
		});

		if (!driver) {
			return errorHandler('Member not found', 404);
		}

		driver = driver.get({ plain: true });
		driver.driver_photo = formatImage(driver.driver_photo, 'driver-uploads');
		driver.vehicle_photo = formatImage(driver.vehicle_photo, 'driver-uploads');

		return res.status(200).json({ success: true, data: formatCase(driver) });
	} catch (error) {
		next(error);
	}
};

exports.updateDriver = async (req, res, next) => {
	try {
		const { driverId } = req;
		const body = formatCase(req.body, 'snake');

		delete body.email_address;
		delete body.password;

		let driver = await Drivers.findByPk(driverId);

		if (!driver) {
			return errorHandler('Driver not found', 404);
		}

		const updatableFields = ['conductor_name', 'shuttle_number', 'plate_number', 'status'];

		const noDataPassed =
			!Object.keys(body).some((key) => updatableFields.includes(key)) &&
			(!req.files || Object.keys(req.files).length === 0);
		const noDataInDb = updatableFields.every((field) => !driver[field]);

		if (noDataPassed && noDataInDb) {
			return errorHandler('No data provided and no existing data found for this driver.', 400);
		}

		const { driverImg, vehicleImg } = req?.files || {};
		if (!driverImg && !driver.driver_photo) {
			return errorHandler('Driver photo is required', 400);
		}

		if (!vehicleImg && !driver.vehicle_photo) {
			return errorHandler('Vehicle photo is required', 400);
		}

		let oldDriverImg, oldVehicleImg;
		if (req.files) {
			if (driverImg && driverImg[0]) {
				body.driver_photo = driverImg[0].filename;
				oldDriverImg = driver.driver_photo;
			}
			if (vehicleImg && vehicleImg[0]) {
				body.vehicle_photo = vehicleImg[0].filename;
				oldVehicleImg = driver.vehicle_photo;
			}
		}

		await driver.update(body);

		if (oldDriverImg) {
			if (process.env.USE_EXTERNAL_FILE_SERVER === 'true') {
				await deleteFilesFromFileServer([oldDriverImg], 'driver-uploads');
			} else {
				deleteFile(oldDriverImg, 'driver-uploads');
			}
		}

		if (oldVehicleImg) {
			if (process.env.USE_EXTERNAL_FILE_SERVER === 'true') {
				await deleteFilesFromFileServer([oldVehicleImg], 'driver-uploads');
			} else {
				deleteFile(oldVehicleImg, 'driver-uploads');
			}
		}

		driver = driver.get({ plain: true });
		delete driver.password;

		return res.status(200).json({ success: true, message: 'Driver updated successfully', source: driver });
	} catch (error) {
		next(error);
	}
};

exports.logout = async (req, res, next) => {
	try {
		const { driverId } = req;

		await Drivers.update(
			{ status: 'offline' },
			{
				where: {
					id: driverId,
				},
			},
		);

		return res.status(200).json({ success: true, message: 'Logged out successfully' });
	} catch (error) {
		next(error);
	}
};
