import { prisma } from '../config/database';
import { AuditAction } from '@prisma/client';
import { logger } from '../config/logger';
import {
    CreateAuditLogParams,
    AuditLogFilters,
    ListAuditLogsResponse,
    AuditLogResponse,
    AuditLogStats,
} from '../types/audit.types';

export class AuditService {
    /**
     * สร้าง audit log entry
     */
    async log(params: CreateAuditLogParams): Promise<void> {
        try {
            await prisma.auditLog.create({
                data: {
                    user_id: params.userId,
                    action: params.action,
                    entity_type: params.entityType,
                    entity_id: params.entityId,
                    old_value: params.oldValue,
                    new_value: params.newValue,
                    ip_address: params.ipAddress,
                    user_agent: params.userAgent,
                    metadata: params.metadata,
                },
            });
        } catch (error) {
            logger.error('Failed to create audit log', { error, params });
        }
    }

    /**
     * Log พร้อม await (สำหรับ critical actions)
     */
    async logSync(params: CreateAuditLogParams): Promise<void> {
        await prisma.auditLog.create({
            data: {
                user_id: params.userId,
                action: params.action,
                entity_type: params.entityType,
                entity_id: params.entityId,
                old_value: params.oldValue,
                new_value: params.newValue,
                ip_address: params.ipAddress,
                user_agent: params.userAgent,
                metadata: params.metadata,
            },
        });
    }

    /**
     * ดึง audit logs พร้อม filters และ pagination
     */
    async getLogs(filters: AuditLogFilters): Promise<ListAuditLogsResponse> {
        const { page = 1, limit = 50 } = filters;
        const skip = (page - 1) * limit;

        const where: any = {};

        if (filters.userId) {
            where.user_id = filters.userId;
        }
        if (filters.action) {
            where.action = filters.action;
        }
        if (filters.entityType) {
            where.entity_type = filters.entityType;
        }
        if (filters.entityId) {
            where.entity_id = filters.entityId;
        }
        if (filters.startDate || filters.endDate) {
            where.created_at = {};
            if (filters.startDate) {
                where.created_at.gte = filters.startDate;
            }
            if (filters.endDate) {
                where.created_at.lte = filters.endDate;
            }
        }

        const [logs, total] = await Promise.all([
            prisma.auditLog.findMany({
                where,
                include: {
                    user: {
                        select: {
                            id: true,
                            username: true,
                            email: true,
                        },
                    },
                },
                orderBy: { created_at: 'desc' },
                skip,
                take: limit,
            }),
            prisma.auditLog.count({ where }),
        ]);

        return {
            data: logs as AuditLogResponse[],
            pagination: {
                page,
                limit,
                total,
                totalPages: Math.ceil(total / limit),
            },
        };
    }

    /**
     * ดึง audit log by ID
     */
    async getLogById(id: number): Promise<AuditLogResponse | null> {
        const log = await prisma.auditLog.findUnique({
            where: { id },
            include: {
                user: {
                    select: {
                        id: true,
                        username: true,
                        email: true,
                    },
                },
            },
        });

        return log as AuditLogResponse | null;
    }

    /**
     * ดึง logs ของ entity เฉพาะ (เช่น ดู history ของ course)
     */
    async getEntityHistory(entityType: string, entityId: number): Promise<AuditLogResponse[]> {
        const logs = await prisma.auditLog.findMany({
            where: {
                entity_type: entityType,
                entity_id: entityId,
            },
            include: {
                user: {
                    select: {
                        id: true,
                        username: true,
                        email: true,
                    },
                },
            },
            orderBy: { created_at: 'desc' },
        });

        return logs as AuditLogResponse[];
    }

    /**
     * ดึง logs ของ user เฉพาะ
     */
    async getUserActivity(userId: number, limit: number = 50): Promise<AuditLogResponse[]> {
        const logs = await prisma.auditLog.findMany({
            where: { user_id: userId },
            include: {
                user: {
                    select: {
                        id: true,
                        username: true,
                        email: true,
                    },
                },
            },
            orderBy: { created_at: 'desc' },
            take: limit,
        });

        return logs as AuditLogResponse[];
    }

    /**
     * ดึงสถิติ audit logs สำหรับ dashboard
     */
    async getStats(): Promise<AuditLogStats> {
        const today = new Date();
        today.setHours(0, 0, 0, 0);

        const [totalLogs, todayLogs, actionCounts, recentActivity] = await Promise.all([
            prisma.auditLog.count(),
            prisma.auditLog.count({
                where: {
                    created_at: { gte: today },
                },
            }),
            prisma.auditLog.groupBy({
                by: ['action'],
                _count: { action: true },
                orderBy: { _count: { action: 'desc' } },
            }),
            prisma.auditLog.findMany({
                include: {
                    user: {
                        select: {
                            id: true,
                            username: true,
                            email: true,
                        },
                    },
                },
                orderBy: { created_at: 'desc' },
                take: 10,
            }),
        ]);

        return {
            totalLogs,
            todayLogs,
            actionSummary: actionCounts.map((item) => ({
                action: item.action,
                count: item._count.action,
            })),
            recentActivity: recentActivity as AuditLogResponse[],
        };
    }

    /**
     * ลบ logs เก่า (สำหรับ maintenance)
     */
    async deleteOldLogs(olderThanDays: number): Promise<number> {
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - olderThanDays);

        const result = await prisma.auditLog.deleteMany({
            where: {
                created_at: { lt: cutoffDate },
            },
        });

        logger.info(`Deleted ${result.count} old audit logs older than ${olderThanDays} days`);
        return result.count;
    }
}

export const auditService = new AuditService();
