import { Response } from 'express';
import { Op } from 'sequelize';
import db from '../../database/models/index.js';
import { AuthRequest } from '../../types/express.types.js';

const { SystemAuditLog, User } = db;

const ACTION_DESCRIPTIONS: Record<string, string> = {
    CREATED: 'Created',
    UPDATED: 'Updated',
    DELETED: 'Deleted',
    ACTIVATED: 'Activated',
    DEACTIVATED: 'Deactivated',
    INITIALIZED: 'Initialized with defaults',
    SUBMITTED: 'Submitted',
    ASSIGNED: 'Assigned',
    UNASSIGNED: 'Unassigned',
    REORDERED: 'Reordered'
};

const MODULE_LABELS: Record<string, string> = {
    QUESTIONNAIRE: 'Questionnaire',
    INTERVIEW_CONFIG: 'Interview Configuration',
    SYSTEM_CONFIG: 'System Configuration',
    SLA_CONFIG: 'SLA Configuration',
    EMAIL_TEMPLATE: 'Email Template',
    MASTER_HIERARCHY: 'Master Hierarchy',
    ROLE_ASSIGNMENT: 'Role Assignment',
    USER_ADMIN: 'User Administration',
    DEALER_MAPPING: 'Dealer Mapping'
};

const formatRow = (row: any) => {
    const log = row.get ? row.get({ plain: true }) : row;
    const actionLabel = ACTION_DESCRIPTIONS[log.action] || log.action;
    const moduleLabel = MODULE_LABELS[log.module] || log.module;
    const target = log.entityLabel ? ` · ${log.entityLabel}` : '';
    const description = log.description || `${moduleLabel}: ${actionLabel}${target}`;

    return {
        id: log.id,
        module: log.module,
        moduleLabel,
        action: log.action,
        actionLabel,
        entityType: log.entityType,
        entityId: log.entityId,
        entityLabel: log.entityLabel,
        description,
        actor: {
            id: log.userId || log.user?.id || null,
            name: log.actorName || log.user?.fullName || 'System',
            role: log.actorRole || null,
            email: log.user?.email || null
        },
        oldData: log.oldData,
        newData: log.newData,
        metadata: log.metadata,
        ipAddress: log.ipAddress,
        userAgent: log.userAgent,
        timestamp: log.createdAt
    };
};

/**
 * GET /api/audit/system-logs
 * Filters: module, entityType, entityId, action, userId, search, dateFrom, dateTo
 * Pagination: page (default 1), limit (default 50, max 200)
 */
export const getSystemAuditLogs = async (req: AuthRequest, res: Response) => {
    try {
        const {
            module,
            entityType,
            entityId,
            action,
            userId,
            search,
            dateFrom,
            dateTo,
            page = '1',
            limit = '50'
        } = req.query as Record<string, string>;

        const pageNum = Math.max(1, parseInt(page, 10) || 1);
        const limitNum = Math.min(200, Math.max(1, parseInt(limit, 10) || 50));
        const offset = (pageNum - 1) * limitNum;

        const where: any = {};
        if (module) where.module = module;
        if (entityType) where.entityType = entityType;
        if (entityId) where.entityId = entityId;
        if (action) where.action = action;
        if (userId) where.userId = userId;

        if (dateFrom || dateTo) {
            where.createdAt = {};
            if (dateFrom) where.createdAt[Op.gte] = new Date(dateFrom);
            if (dateTo) where.createdAt[Op.lte] = new Date(dateTo);
        }

        if (search) {
            where[Op.or] = [
                { entityLabel: { [Op.iLike]: `%${search}%` } },
                { description: { [Op.iLike]: `%${search}%` } },
                { actorName: { [Op.iLike]: `%${search}%` } }
            ];
        }

        const { count, rows } = await SystemAuditLog.findAndCountAll({
            where,
            include: [
                {
                    model: User,
                    as: 'user',
                    attributes: ['id', 'fullName', 'email']
                }
            ],
            order: [['createdAt', 'DESC']],
            limit: limitNum,
            offset
        });

        return res.json({
            success: true,
            data: rows.map(formatRow),
            pagination: {
                total: count,
                page: pageNum,
                limit: limitNum,
                totalPages: Math.ceil(count / limitNum)
            }
        });
    } catch (error) {
        console.error('Get system audit logs error:', error);
        return res
            .status(500)
            .json({ success: false, message: 'Error fetching system audit logs' });
    }
};

/**
 * GET /api/audit/system-summary
 * Returns counts grouped by module + the most recent activity row.
 */
export const getSystemAuditSummary = async (_req: AuthRequest, res: Response) => {
    try {
        const counts = (await SystemAuditLog.findAll({
            attributes: [
                'module',
                [db.sequelize.fn('COUNT', db.sequelize.col('id')), 'total']
            ],
            group: ['module'],
            order: [[db.sequelize.literal('total'), 'DESC']]
        })) as any[];

        const lastRow = await SystemAuditLog.findOne({
            include: [{ model: User, as: 'user', attributes: ['id', 'fullName', 'email'] }],
            order: [['createdAt', 'DESC']]
        });

        const total = counts.reduce(
            (sum: number, row: any) => sum + Number(row.get('total') || 0),
            0
        );

        return res.json({
            success: true,
            data: {
                totalEntries: total,
                byModule: counts.map((row: any) => ({
                    module: row.module,
                    moduleLabel: MODULE_LABELS[row.module] || row.module,
                    total: Number(row.get('total') || 0)
                })),
                lastActivity: lastRow ? formatRow(lastRow) : null
            }
        });
    } catch (error) {
        console.error('Get system audit summary error:', error);
        return res
            .status(500)
            .json({ success: false, message: 'Error fetching system audit summary' });
    }
};
