import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateFollowupDto } from './dto/create-followup.dto';
import { NotificationsService } from '../notifications/notifications.service';
import { WhatsappService } from '../whatsapp/whatsapp.service';

@Injectable()
export class FollowupsService {
    constructor(
        private prisma: PrismaService,
        private notifications: NotificationsService,
        private whatsappService: WhatsappService
    ) { }

    async create(createFollowupDto: CreateFollowupDto) {
        // Map description to notes if provided, and exclude 'time' which is only used by the frontend
        const { description, time, ...rest } = createFollowupDto as any;
        const data = {
            ...rest,
            notes: rest.notes || description, // Use description if notes is empty
        };

        const followup = await this.prisma.followup.create({
            data,
            include: { client: true }
        });

        // Trigger WhatsApp followup reminder to client
        if (followup.client?.phone) {
            try {
                await this.whatsappService.sendFollowupReminder(
                    followup.client.phone,
                    followup.client.name,
                    new Date(followup.date).toLocaleString()
                );
            } catch (err) {
                console.error('Failed to send followup WhatsApp:', err.message);
            }
        }

        // Send Alert to Assigned User if different from creator
        if (data.userId) {
            await this.notifications.create(
                data.userId,
                'New Follow-up Assigned 📅',
                `You have been assigned a new follow-up task for client. Deadline: ${new Date(data.date).toLocaleString()}`,
                'FOLLOWUP_ASSIGNED'
            );
        }

        return followup;
    }

    findAll(filters?: { userId?: string; clientId?: string; dateFrom?: string; dateTo?: string; status?: string; opportunityId?: string; enquiryId?: string }) {
        const where: any = {};
        if (filters?.userId) where.userId = filters.userId;
        if (filters?.clientId) where.clientId = filters.clientId;
        if (filters?.status) where.status = filters.status;
        if (filters?.opportunityId) where.opportunityId = filters.opportunityId;
        if (filters?.enquiryId) where.enquiryId = filters.enquiryId;
        if (filters?.dateFrom || filters?.dateTo) {
            where.date = {};
            if (filters.dateFrom) where.date.gte = new Date(filters.dateFrom);
            if (filters.dateTo) where.date.lte = new Date(filters.dateTo);
        }
        return this.prisma.followup.findMany({
            where,
            include: { client: true, user: true, enquiry: { include: { products: true } }, opportunity: true },
            orderBy: { date: 'asc' }
        });
    }

    findOne(id: string) {
        return this.prisma.followup.findUnique({
            where: { id },
            include: { client: true, user: true, enquiry: true }
        });
    }

    async update(id: string, updateFollowupDto: any) {
        // Fetch current state before update to detect reassignment
        const existing = await this.prisma.followup.findUnique({ where: { id } });

        const followup = await this.prisma.followup.update({
            where: { id },
            data: updateFollowupDto,
            include: { user: true, client: true }
        });

        // Auto-dismiss notification when marked DONE
        if (updateFollowupDto.status === 'DONE' && followup.userId) {
            await this.prisma.$executeRaw`
                UPDATE notification 
                SET isRead = true 
                WHERE userId = ${followup.userId} 
                AND type = 'FOLLOWUP_ASSIGNED' 
                AND isRead = false
            `;
        }

        // Handle Reassignment — new userId provided and it's different from existing
        if (updateFollowupDto.userId && existing && updateFollowupDto.userId !== existing.userId) {
            // Dismiss old assignee's notification
            if (existing.userId) {
                await this.prisma.$executeRaw`
                    UPDATE notification SET isRead = true 
                    WHERE userId = ${existing.userId} AND type = 'FOLLOWUP_ASSIGNED' AND isRead = false
                `;
            }
            // Notify new assignee
            const deadline = new Date(followup.date).toLocaleString();
            await this.notifications.create(
                updateFollowupDto.userId,
                'Follow-up Reassigned to You 📅',
                `A follow-up task for ${followup.client?.name || 'a client'} has been reassigned to you. Deadline: ${deadline}`,
                'FOLLOWUP_ASSIGNED'
            );
        }

        // Auto-sync DEMO feedback to Opportunity
        if (updateFollowupDto.status === 'DONE' && (followup.type === 'DEMO' || followup.type === 'DEMO_COMPLETED') && followup.opportunityId) {
            await this.prisma.opportunity.update({
                where: { id: followup.opportunityId },
                data: {
                    isDemoDone: true,
                    demoPersonName: followup.demoPersonName,
                    demoContactDetails: followup.demoContactDetails,
                    keyQueries: followup.keyQueries,
                    competitorMention: followup.competitorMention
                }
            });
        }

        return followup;
    }

    remove(id: string) {
        return this.prisma.followup.delete({ where: { id } });
    }
}
