import { NextRequest, NextResponse } from 'next/server';
import dbConnect from '../../src/lib/mongodb';
import User from '../../src/models/User';
import UserType from '../../src/models/UserType';
import bcrypt from 'bcryptjs';

function generatePassword(len = 8) {
	const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()';
	let out = '';
	for (let i = 0; i < len; i++) out += chars[Math.floor(Math.random() * chars.length)];
	return out;
}

// GET: list customers or get single customer by id
export async function GET(request: NextRequest, context?: { params: Promise<any> }) {
	try {
		await dbConnect();

		const userType = await UserType.findOne({ roleId: 2 });
		if (!userType) {
			return NextResponse.json({ success: false, error: 'Customer role not configured' }, { status: 500 });
		}

		const { searchParams } = new URL(request.url);
		const page = parseInt(searchParams.get('page') || '1');
        const limit = parseInt(searchParams.get('limit') || '10');
        const search = searchParams.get('search');

        const sortBy = searchParams.get('sortBy') || 'createdAt';
        const sortOrder = searchParams.get('sortOrder') || 'desc';

		const url = new URL(request.url);
		const last = url.pathname.split('/').pop();

		// If last path segment looks like an object id, treat as detail
		if (last && last.length === 24) {
			const user = await User.findById(last).populate('role', 'role roleId');
			if (!user) return NextResponse.json({ success: false, error: 'Customer not found' }, { status: 404 });
			// ensure user is a customer
			if (!user.role || String(user.role._id) !== String(userType._id)) {
				return NextResponse.json({ success: false, error: 'Not a customer' }, { status: 404 });
			}

			return NextResponse.json({ success: true, data: user });
		}

		const skip = (page - 1) * limit;

		const query: any = { role: userType._id };
		if (search) {
			query.$or = [
				{ name: { $regex: search, $options: 'i' } },
				{ email: { $regex: search, $options: 'i' } },
				{ phone: { $regex: search, $options: 'i' } }
			];
		}

		const allowedSortFields = ['name', 'email', 'createdAt'];

        const sortField = allowedSortFields.includes(sortBy)
            ? sortBy
            : 'createdAt';

        const customers = await User.find(query)
            .select('name email phone status createdAt')
            .sort({
                [sortField]: sortOrder === 'asc' ? 1 : -1
            })
            .skip(skip)
            .limit(limit);

		const total = await User.countDocuments(query);

		return NextResponse.json({
			success: true,
			data: customers,
			pagination: { page, limit, total, pages: Math.ceil(total / limit) }
		});

	} catch (error: any) {
		console.error('Error in customer GET:', error);
		return NextResponse.json({ success: false, error: error.message || 'Failed to fetch customers' }, { status: 500 });
	}
}

// PUT: admin actions - reset password or update status
export async function PUT(request: NextRequest, context?: { params: Promise<any> }) {
	try {
		await dbConnect();

		const body = await request.json();
		const { action, id, status, newPassword } = body;

		if (!action || !id) {
			return NextResponse.json({ success: false, error: 'Action and id are required' }, { status: 400 });
		}

		const userType = await UserType.findOne({ roleId: 2 });
		if (!userType) {
			return NextResponse.json({ success: false, error: 'Customer role not configured' }, { status: 500 });
		}

		const user = await User.findById(id).select('+password');
		if (!user) return NextResponse.json({ success: false, error: 'Customer not found' }, { status: 404 });

		// ensure target is a customer
		if (String(user.role) !== String(userType._id)) {
			return NextResponse.json({ success: false, error: 'Not a customer' }, { status: 400 });
		}

		if (action === 'resetPassword') {
			if (!newPassword || typeof newPassword !== 'string' || newPassword.length < 6) {
				return NextResponse.json({ success: false, error: 'New password must be at least 6 characters' }, { status: 400 });
			}

			const hashed = await bcrypt.hash(newPassword, 12);
			user.password = hashed;
			user.passwordChangedAt = new Date();
			await user.save();

			return NextResponse.json({ success: true, message: 'Password reset successfully' });
		}

		if (action === 'setStatus') {
			if (!status || (status !== 'active' && status !== 'inactive')) {
				return NextResponse.json({ success: false, error: 'Invalid status' }, { status: 400 });
			}

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

			return NextResponse.json({ success: true, message: `Status updated to ${status}` });
		}

		return NextResponse.json({ success: false, error: 'Unknown action' }, { status: 400 });

	} catch (error: any) {
		console.error('Error in customer PUT:', error);
		return NextResponse.json({ success: false, error: error.message || 'Failed to perform action' }, { status: 500 });
	}
}

