import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { UsersService } from '../users/users.service';
import { user_role } from '@prisma/client';
import { startOfDay, startOfMonth } from 'date-fns';

@Injectable()
export class DashboardService {
    constructor(
        private readonly prisma: PrismaService,
        private readonly usersService: UsersService
    ) { }

    async getStats(user: any) {
        let allowedUserIds: string[] = [user.id];

        if (user.role === user_role.ADMIN) {
            // Admin sees everything, leave allowedUserIds empty or filter differently
            // But for simplicity in query, we can use empty where if Admin
        } else {
            const subordinates = await this.usersService.getSubordinateIds(user.id);
            allowedUserIds = [user.id, ...subordinates];
        }

        const userFilter = user.role === user_role.ADMIN ? {} : { userId: { in: allowedUserIds } };
        const leadSharingFilter = user.role === user_role.ADMIN ? {} : { OR: [{ assignedTo: { in: allowedUserIds } }, { creatorId: { in: allowedUserIds } }] };
        const clientFilter = user.role === user_role.ADMIN ? {} : { assignedTo: { in: allowedUserIds } };

        const today = startOfDay(new Date());
        const monthStart = startOfMonth(new Date());

        const [
            enquiriesCount,
            enquiriesToday,
            opportunityStats,
            monthlyRevenue,
            clientsCount,
            recentEnquiries,
            recentOpportunities,
            pendingExpenses,
            overdueFollowups,
            todayFollowups,
            newItems
        ] = await Promise.all([
            // Total Enquiries
            this.prisma.enquiry.count({ where: userFilter }),
            
            // Enquiries Today
            this.prisma.enquiry.count({
                where: {
                    ...userFilter,
                    createdAt: { gte: today }
                }
            }),

            // Pipeline Stats (Non-WON)
            this.prisma.opportunity.aggregate({
                where: {
                    ...leadSharingFilter,
                    stage: { not: 'WON' }
                },
                _sum: { value: true },
                _count: true
            }),

            // Monthly Revenue (WON this month)
            this.prisma.opportunity.aggregate({
                where: {
                    ...leadSharingFilter,
                    stage: 'WON',
                    updatedAt: { gte: monthStart }
                },
                _sum: { value: true }
            }),

            // Total Customers (for conversion rate)
            this.prisma.client.count({
                where: {
                    ...clientFilter,
                    status: { in: ['SALES', 'CLOSED'] }
                }
            }),

            // Recent Activity - Enquiries
            this.prisma.enquiry.findMany({
                where: userFilter,
                take: 5,
                orderBy: { createdAt: 'desc' },
                include: { client: true, user: true }
            }),

            // Recent Activity - Opportunities
            this.prisma.opportunity.findMany({
                where: leadSharingFilter,
                take: 5,
                orderBy: { updatedAt: 'desc' },
                include: { client: true, user: true }
            }),

            // Pending Expenses (Managers/Admins)
            this.prisma.expense.count({
                where: {
                    ...userFilter,
                    status: 'PENDING'
                }
            }),

            // Overdue Followups
            this.prisma.followup.count({
                where: {
                    ...userFilter,
                    status: 'PENDING',
                    date: { lt: today }
                }
            }),

            // Today's Followups
            this.prisma.followup.count({
                where: {
                    ...userFilter,
                    status: 'PENDING',
                    date: { gte: today, lt: new Date(today.getTime() + 86400000) }
                }
            }),

            // New Leads/Opportunities (Last 24h)
            this.prisma.opportunity.count({
                where: {
                    ...leadSharingFilter,
                    createdAt: { gte: new Date(Date.now() - 24 * 60 * 60 * 1000) }
                }
            })
        ]);

        // Fetch Latest Performance Score
        const latestScore = await this.prisma.performanceScore.findFirst({
            where: { userId: user.id },
            orderBy: { date: 'desc' }
        });

        // Fetch Current Target
        const target = await this.prisma.target.findFirst({
            where: { userId: user.id, month: new Date().getMonth() + 1, year: new Date().getFullYear() }
        });

        // Calculate Contribution Revenue (50/50 Split)
        const wonOpportunities = await this.prisma.opportunity.findMany({
            where: {
                ...leadSharingFilter,
                stage: 'WON',
                updatedAt: { gte: monthStart }
            },
            select: { value: true, assignedTo: true, creatorId: true }
        });

        const contributionRevenue = wonOpportunities.reduce((total, o) => {
            let share = 0;
            const isCloser = o.assignedTo === user.id;
            const isCreator = o.creatorId === user.id;
            if (isCloser && isCreator) share = o.value;
            else if (isCloser || isCreator) share = o.value * 0.5;
            return total + share;
        }, 0);

        // Calculate Conversion Rate
        const conversionRate = enquiriesCount > 0 
            ? Math.round((clientsCount / enquiriesCount) * 100) 
            : 0;

        return {
            kpis: {
                enquiriesToday,
                pipelineValue: opportunityStats._sum.value || 0,
                pipelineCount: opportunityStats._count || 0,
                monthlyRevenue: monthlyRevenue._sum.value || 0,
                contributionRevenue,
                conversionRate,
                pendingExpenses: (user.role === user_role.ADMIN || [user_role.GENERAL_MANAGER, user_role.MANAGER, user_role.OFFICER].includes(user.role)) ? pendingExpenses : 0,
                overdueCount: overdueFollowups,
                todayCount: todayFollowups,
                newCount: newItems
            },
            performance: latestScore ? {
                score: latestScore.score,
                tag: latestScore.tag,
                breakdown: {
                    revenue: latestScore.revenueScore,
                    conversion: latestScore.conversionScore,
                    activity: latestScore.activityScore,
                    discipline: latestScore.disciplineScore,
                    quality: latestScore.dataQualityScore
                }
            } : null,
            target: target ? {
                monthly: target.monthlyTarget,
                minimum: target.minTarget,
                weekly: target.weeklyTarget,
                dailyLead: target.dailyLeadTarget,
                achieved: monthlyRevenue._sum.value || 0
            } : null,
            recentActivity: {
                enquiries: recentEnquiries,
                opportunities: recentOpportunities
            }
        };
    }
}
