import { db } from '../config/database.js';
import { auditLogs, users } from '../db/schema.js';
import { desc, eq, and, gte, lte, like, sql } from 'drizzle-orm';

export const getRecentAuditLogs = async (req, res, next) => {
  try {
    const {
      page = 1,
      limit = 50,
      userId,
      action,
      resource,
      dateFrom,
      dateTo,
    } = req.query;

    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    const offset = (pageNum - 1) * limitNum;

    // Build conditions array
    const conditions = [];

    if (userId) {
      conditions.push(eq(auditLogs.userId, userId));
    }

    if (action) {
      conditions.push(eq(auditLogs.action, action));
    }

    if (resource) {
      conditions.push(eq(auditLogs.resource, resource));
    }

    if (dateFrom) {
      conditions.push(gte(auditLogs.createdAt, new Date(dateFrom)));
    }

    if (dateTo) {
      // Add one day to include the entire end date
      const endDate = new Date(dateTo);
      endDate.setDate(endDate.getDate() + 1);
      conditions.push(lte(auditLogs.createdAt, endDate));
    }

    const whereClause = conditions.length > 0 ? and(...conditions) : undefined;

    // Get total count for pagination
    const [countResult] = await db
      .select({ count: sql`count(*)::int` })
      .from(auditLogs)
      .where(whereClause);

    const totalCount = countResult?.count || 0;
    const totalPages = Math.ceil(totalCount / limitNum);

    // Get paginated logs
    const logs = await db
      .select({
        id: auditLogs.id,
        userId: auditLogs.userId,
        action: auditLogs.action,
        resource: auditLogs.resource,
        resourceId: auditLogs.resourceId,
        oldValue: auditLogs.oldValue,
        newValue: auditLogs.newValue,
        ipAddress: auditLogs.ipAddress,
        success: auditLogs.success,
        createdAt: auditLogs.createdAt,
        // User info
        userFirstName: users.firstName,
        userLastName: users.lastName,
        username: users.username,
      })
      .from(auditLogs)
      .leftJoin(users, eq(auditLogs.userId, users.id))
      .where(whereClause)
      .orderBy(desc(auditLogs.createdAt))
      .limit(limitNum)
      .offset(offset);

    res.json({
      success: true,
      data: {
        logs,
        pagination: {
          page: pageNum,
          limit: limitNum,
          totalCount,
          totalPages,
          hasNextPage: pageNum < totalPages,
          hasPrevPage: pageNum > 1,
        },
      },
    });
  } catch (error) {
    next(error);
  }
};

// Get distinct actions for filter dropdown
export const getAuditActions = async (req, res, next) => {
  try {
    const actions = await db
      .selectDistinct({ action: auditLogs.action })
      .from(auditLogs)
      .orderBy(auditLogs.action);

    res.json({
      success: true,
      data: actions.map((a) => a.action),
    });
  } catch (error) {
    next(error);
  }
};

// Get distinct resources for filter dropdown
export const getAuditResources = async (req, res, next) => {
  try {
    const resources = await db
      .selectDistinct({ resource: auditLogs.resource })
      .from(auditLogs)
      .orderBy(auditLogs.resource);

    res.json({
      success: true,
      data: resources.map((r) => r.resource),
    });
  } catch (error) {
    next(error);
  }
};
