import Invoice from '../model/Invoice.js'
import Inventory from '../model/Inventory.js'
import Service from '../model/Service.js'

const getAnalysis = async (req, res) => {
	try {
		const userId = req.user?.id || req.query.userId
		if (!userId) {
			return res.status(400).json({ success: false, message: 'userId is required' })
		}

		const invoices = await Invoice.find({ userId }).populate('products.inventoryId').populate('serviceId')
		const inventoryItems = await Inventory.find({ userId })

		const invoiceCount = invoices.length
		const totalRevenue = invoices.reduce((sum, invoice) => sum + (invoice.finalAmount ?? 0), 0)
		const totalDiscount = invoices.reduce((sum, invoice) => sum + ((invoice.discountValue ?? invoice.discontValue ?? 0) ?? 0), 0)
		const totalProductsSold = invoices.reduce(
			(sum, invoice) => sum + (invoice.products?.reduce((count, item) => count + (item.quantity ?? 0), 0) ?? 0),
			0
		)

		let totalProfit = 0
		const productMap = new Map()
		const revenueTrendMap = {}
		const vehicleMap = new Map()

		invoices.forEach((invoice) => {
			const createdAt = invoice.createdAt || invoice.updatedAt
			if (createdAt) {
				const month = `${createdAt.getFullYear()}-${String(createdAt.getMonth() + 1).padStart(2, '0')}`
				revenueTrendMap[month] = (revenueTrendMap[month] ?? 0) + (invoice.finalAmount ?? 0)
			}

			if (invoice.serviceId?.vehicleNumber) {
				const vn = invoice.serviceId.vehicleNumber
				vehicleMap.set(vn, (vehicleMap.get(vn) || 0) + 1)
			}

			invoice.products?.forEach((product) => {
				const quantity = product.quantity ?? 0
				const revenue = (product.price ?? 0) * quantity
				const cost = (product.inventoryId?.purchasePrice ?? 0) * quantity
				totalProfit += revenue - cost

				const productName = product.name || product.inventoryId?.name || 'Unknown'
				const existing = productMap.get(productName) || { name: productName, quantity: 0, revenue: 0, cost: 0 }
				existing.quantity += quantity
				existing.revenue += revenue
				existing.cost += cost
				productMap.set(productName, existing)
			})
		})

		const revenueTrend = Object.entries(revenueTrendMap)
			.sort((a, b) => a[0].localeCompare(b[0]))
			.map(([month, revenue]) => ({ month, revenue }))

		const topProducts = Array.from(productMap.values())
			.sort((a, b) => b.revenue - a.revenue)
			.slice(0, 5)

		const totalUniqueCustomers = vehicleMap.size
		const repeatCustomers = Array.from(vehicleMap.values()).filter(count => count > 1).length
		const repeatCustomerPercentage = totalUniqueCustomers > 0 ? (repeatCustomers / totalUniqueCustomers) * 100 : 0

		const inventoryCount = inventoryItems.length
		const totalStockValue = inventoryItems.reduce(
			(sum, item) => sum + ((item.stockPrice ?? (item.purchasePrice ?? 0) * (item.quantity ?? 0)) ?? 0),
			0
		)
		const lowStockCount = inventoryItems.filter((item) => item.quantity !== undefined && item.quantity <= 5).length
		const outOfStockCount = inventoryItems.filter((item) => item.quantity === 0).length

		const averageInvoiceValue = invoiceCount ? totalRevenue / invoiceCount : 0
		const grossMarginPercent = totalRevenue ? (totalProfit / totalRevenue) * 100 : 0
		const totalService=await Service.countDocuments({ userId })
		return res.json({
			success: true,
			data: {
				totalService,
				invoiceCount,
				totalRevenue,
				totalProfit,
				grossMarginPercent,
				totalDiscount,
				totalProductsSold,
				averageInvoiceValue,
				revenueTrend,
				topProducts,
				inventoryCount,
				totalStockValue,
				lowStockCount,
				outOfStockCount,
				inventoryItems,
				repeatCustomerPercentage,
			}
		})
	} catch (err) {
		console.error(err)
		return res.status(500).json({ success: false, message: 'Server error', error: err.message })
	}
}
const getDashboardAnalytics = async (req, res) => {
	try {
		const userId = req.user?.id 
		if (!userId) {
			return res.status(400).json({ message: 'userId is required' })
		}
		const todayService=await Service.countDocuments({ userId, createdAt: { $gte: new Date(new Date().setHours(0, 0, 0, 0)) } })
		const todayRevenue=await Invoice.aggregate([
			{ $match: { userId, createdAt: { $gte: new Date(new Date().setHours(0, 0, 0, 0)) } } },
			{ $group: { _id: null, total: { $sum: "$finalAmount" } } }
		])
		const totalServices=await Service.countDocuments({ userId })
		const totalRevenue=await Invoice.aggregate([
			{ $match: { userId } },
			{ $group: { _id: null, total: { $sum: "$finalAmount" } } }
		])

		const pendingServices=await Service.countDocuments({ userId, status: 'pending' })
		const completedServices=await Service.countDocuments({ userId, status: 'delivered' })
		const lowStock = await Inventory.countDocuments({ userId, quantity: { $lte: 5 } })
		const lowStockItems = await Inventory.find({ userId, quantity: { $lte: 5 } }).select('name quantity')
		return res.json({
			success: true,
			data: {
				todayService,
				todayRevenue: todayRevenue[0]?.total || 0,
				totalServices,
				totalRevenue: totalRevenue[0]?.total || 0,
				pendingServices,
				completedServices,
				lowStock,
				lowStockItems,
			}
		})

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

const getCalendarData = async (req, res) => {
	try {
		const userId = req.user?.id || req.query.userId
		if (!userId) {
			return res.status(400).json({ success: false, message: 'userId is required' })
		}

		const now = new Date()
		const currentYear = req.query.year ? parseInt(req.query.year) : now.getFullYear()
		const currentMonth = req.query.month ? parseInt(req.query.month) : now.getMonth()
		
		// Get first day of current month and last day of current month
		const firstDayOfMonth = new Date(currentYear, currentMonth, 1)
		const lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0)

		// Get services for current month grouped by date
		const servicesData = await Service.aggregate([
			{
				$match: {
					userId: userId,
					createdAt: { $gte: firstDayOfMonth, $lte: lastDayOfMonth }
				}
			},
			{
				$group: {
					_id: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } },
					serviceCount: { $sum: 1 }
				}
			},
			{ $sort: { _id: 1 } }
		])

		// Get invoices for current month grouped by date
		const invoicesData = await Invoice.aggregate([
			{
				$match: {
					userId: userId,
					createdAt: { $gte: firstDayOfMonth, $lte: lastDayOfMonth }
				}
			},
			{
				$group: {
					_id: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } },
					revenue: { $sum: '$finalAmount' },
					cost: { $sum: { $ifNull: ['$totalCost', 0] } },
					invoiceCount: { $sum: 1 }
				}
			},
			{ $sort: { _id: 1 } }
		])

		// Create a map for easy lookup
		const serviceMap = new Map(servicesData.map(item => [item._id, item.serviceCount]))
		const invoiceMap = new Map(invoicesData.map(item => [item._id, item]))

		// Combine data into calendar format
		const calendarData = {}
		
		// Get all unique dates from both services and invoices
		const allDates = new Set([
			...servicesData.map(s => s._id),
			...invoicesData.map(i => i._id)
		])

		// Fill in data for each date in the current month
		for (let day = 1; day <= lastDayOfMonth.getDate(); day++) {
			const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`
			const serviceCount = serviceMap.get(dateStr) || 0
			const invoiceData = invoiceMap.get(dateStr) || { revenue: 0, cost: 0 }
			
			calendarData[day] = {
				date: dateStr,
				day: day,
				serviceCount,
				revenue: invoiceData.revenue || 0,
				profit: (invoiceData.revenue || 0) - (invoiceData.cost || 0)
			}
		}

		return res.json({
			success: true,
			data: {
				month: currentMonth + 1,
				year: currentYear,
				daysInMonth: lastDayOfMonth.getDate(),
				calendarData
			}
		})
	} catch (err) {
		console.error(err)
		return res.status(500).json({ success: false, message: 'Server error', error: err.message })
	}
}

const getDateRecords = async (req, res) => {
	try {
		const userId = req.user?.id || req.query.userId
		const { date } = req.params

		if (!userId) {
			return res.status(400).json({ success: false, message: 'userId is required' })
		}
		if (!date) {
			return res.status(400).json({ success: false, message: 'date is required' })
		}

		// date is in YYYY-MM-DD format
		const startOfDay = new Date(date)
		startOfDay.setHours(0, 0, 0, 0)
		const endOfDay = new Date(date)
		endOfDay.setHours(23, 59, 59, 999)

		const services = await Service.find({
			userId,
			createdAt: { $gte: startOfDay, $lte: endOfDay }
		}).sort({ createdAt: -1 })

		const invoices = await Invoice.find({
			userId,
			createdAt: { $gte: startOfDay, $lte: endOfDay }
		}).populate('serviceId').sort({ createdAt: -1 })

		return res.json({
			success: true,
			data: {
				services,
				invoices
			}
		})
	} catch (err) {
		console.error(err)
		return res.status(500).json({ success: false, message: 'Server error', error: err.message })
	}
}

export default {
	getAnalysis,
	getDashboardAnalytics,
	getCalendarData,
	getDateRecords
}
