import bcrypt from 'bcrypt'
import jwt from 'jsonwebtoken'
import crypto from 'crypto'
import User from '../model/User.js'

const register = async (req, res) => {
	try {
		const { garageName, email, phoneNumber, password, logo } = req.body
		if (!email || !password) return res.status(400).json({ message: 'Email and password required' })
		const existing = await User.findOne({ $or: [{ email }, { phoneNumber }] })
		if (existing) return res.status(400).json({ message: 'User with given email or phone already exists' })
		const hashed = await bcrypt.hash(password, 10)
		const user = new User({ garageName, email, phoneNumber, password: hashed, logo })
		await user.save()
		res.status(201).json({ message: 'User registered',success:true})
	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message })
	}
}

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

		if (!email || !password) {
			return res.status(400).json({ message: 'Email and password required', success: false });
		}

		const user = await User.findOne({ email });
		if (!user) {
			return res.status(400).json({ message: 'Invalid credentials', success: false });
		}

		const match = await bcrypt.compare(password, user.password);
		if (!match) {
			return res.status(400).json({ message: 'Invalid credentials', success: false });
		}

		const accessToken = jwt.sign(
			{ id: user._id, email: user.email },
			process.env.JWT_SECRET || 'secret',
			{ expiresIn: '15m' }
		);

		const refreshToken = jwt.sign(
			{ id: user._id, email: user.email },
			process.env.JWT_SECRET || 'secret',
			{ expiresIn: '7d' }
		);

		user.refreshToken = refreshToken;
		await user.save();

		// 🔥 Send refresh token in cookie
		res.cookie('refreshToken', refreshToken, {
			httpOnly: true,
			secure: false, // true in production (HTTPS)
			sameSite: 'Strict',
			maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
		});

		res.json({
			message: 'Login successful',
			accessToken,
			userId: user._id,
			success: true
		});

	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message });
	}
};

const forgotPassword = async (req, res) => {
	try {
		const { email } = req.body
		if (!email) return res.status(400).json({ message: 'Email required' })
		const user = await User.findOne({ email })
		if (!user) return res.status(400).json({ message: 'No user with that email' })
		const token = crypto.randomBytes(20).toString('hex')
		user.resetPasswordToken = token
		user.resetPasswordExpires = Date.now() + 3600000
		await user.save()
		// In a production app you'd send the token via email. Return token for testing.
		res.json({ message: 'Reset token generated', resetToken: token, expiresIn: 3600 })
	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message })
	}
}

const resetPassword = async (req, res) => {
	try {
		const { token, newPassword } = req.body
		if (!token || !newPassword) return res.status(400).json({ message: 'Token and newPassword required' })
		const user = await User.findOne({ resetPasswordToken: token, resetPasswordExpires: { $gt: Date.now() } })
		if (!user) return res.status(400).json({ message: 'Invalid or expired token' })
		user.password = await bcrypt.hash(newPassword, 10)
		user.resetPasswordToken = undefined
		user.resetPasswordExpires = undefined
		await user.save()
		res.json({ message: 'Password reset successful' })
	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message })
	}
}

const changePassword = async (req, res) => {
	try {
		const { userId, currentPassword, newPassword } = req.body
		if (!userId || !currentPassword || !newPassword) return res.status(400).json({ message: 'Required fields missing' })
		const user = await User.findById(userId)
		if (!user) return res.status(404).json({ message: 'User not found' })
		const match = await bcrypt.compare(currentPassword, user.password)
		if (!match) return res.status(400).json({ message: 'Current password incorrect' })
		user.password = await bcrypt.hash(newPassword, 10)
		await user.save()
		res.json({ message: 'Password changed' })
	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message })
	}
}

const deleteAccount = async (req, res) => {
	try {
		const { userId, password } = req.body
		if (!userId || !password) return res.status(400).json({ message: 'Required fields missing' })
		const user = await User.findById(userId)
		if (!user) return res.status(404).json({ message: 'User not found' })
		const match = await bcrypt.compare(password, user.password)
		if (!match) return res.status(400).json({ message: 'Password incorrect' })
		await User.deleteOne({ _id: userId })
		res.json({ message: 'Account deleted' })
	} catch (err) {
		res.status(500).json({ message: 'Server error', error: err.message })
	}
}

const refreshAccessToken = async (req, res) => {
	try {
		const token = req.cookies.refreshToken;

		if (!token) {
			return res.status(401).json({ message: 'No refresh token' });
		}

		const decoded = jwt.verify(
			token,
			process.env.JWT_SECRET || 'secret'
		);

		const accessToken = jwt.sign(
			{ id: decoded.id, email: decoded.email },
			process.env.JWT_SECRET || 'secret',
			{ expiresIn: '15m' }
		);

		res.json({ accessToken });

	} catch (err) {
		return res.status(403).json({ message: 'Invalid refresh token' });
	}
};

const logout = async (req, res) => {
	try {
		const token = req.cookies.refreshToken;

		// If no cookie, just return success (already logged out)
		if (!token) {
			return res.json({ message: 'Logged out successfully' });
		}

		// Optional but recommended: remove token from DB
		const user = await User.findOne({ refreshToken: token });

		if (user) {
			user.refreshToken = null;
			await user.save();
		}

		// 🔥 Clear cookie
		res.clearCookie('refreshToken', {
			httpOnly: true,
			secure: false, // true in production (HTTPS)
			sameSite: 'Strict'
		});

		return res.json({ message: 'Logged out successfully' });

	} catch (err) {
		return res.status(500).json({
			message: 'Logout failed',
			error: err.message
		});
	}
};

export  {
	register,
	changePassword,
	login,
	forgotPassword,
	resetPassword,
	deleteAccount,
	refreshAccessToken,
	logout,
}
