import { Response } from "express";
import { AuthenticatedRequest } from "../middleware/authMiddleware";
import { auditLogService, getClientIp, AuditAction, AuditResourceType } from "../services/auditLogService";
import { query } from "../database/db";
import logger from "../utils/logger";

export const getAuditLogs = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const userCompanyCode = req.user?.companyCode;
    const isSuperAdmin = req.user?.userType === "SUPER_ADMIN";

    const {
      companyCode,
      userId,
      resourceType,
      action,
      tableName,
      dateFrom,
      dateTo,
      search,
      page,
      limit,
    } = req.query;

    const result = await auditLogService.queryLogs(
      {
        companyCode: (companyCode as string) || (isSuperAdmin ? undefined : userCompanyCode),
        userId: userId as string,
        resourceType: resourceType as string,
        action: action as string,
        tableName: tableName as string,
        dateFrom: dateFrom as string,
        dateTo: dateTo as string,
        search: search as string,
        page: page ? parseInt(page as string, 10) : 1,
        limit: limit ? parseInt(limit as string, 10) : 50,
      },
      isSuperAdmin
    );

    res.json({
      success: true,
      data: result.data,
      total: result.total,
      page: page ? parseInt(page as string, 10) : 1,
      limit: limit ? parseInt(limit as string, 10) : 50,
    });
  } catch (error: any) {
    logger.error("감사 로그 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "감사 로그 조회 중 오류가 발생했습니다.",
    });
  }
};

export const getAuditLogStats = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const userCompanyCode = req.user?.companyCode;
    const isSuperAdmin = req.user?.userType === "SUPER_ADMIN";
    const { companyCode, days } = req.query;

    const targetCompany = isSuperAdmin
      ? (companyCode as string) || undefined
      : userCompanyCode;

    const stats = await auditLogService.getStats(
      targetCompany,
      days ? parseInt(days as string, 10) : 30
    );

    res.json({ success: true, data: stats });
  } catch (error: any) {
    logger.error("감사 로그 통계 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "감사 로그 통계 조회 중 오류가 발생했습니다.",
    });
  }
};

export const getAuditLogUsers = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const userCompanyCode = req.user?.companyCode;
    const isSuperAdmin = req.user?.userType === "SUPER_ADMIN";
    const { companyCode } = req.query;

    const conditions: string[] = ["LOWER(u.status) = 'active'"];
    const params: any[] = [];
    let paramIndex = 1;

    if (!isSuperAdmin) {
      conditions.push(`u.company_code = $${paramIndex++}`);
      params.push(userCompanyCode);
    } else if (companyCode) {
      conditions.push(`u.company_code = $${paramIndex++}`);
      params.push(companyCode);
    }

    if (!isSuperAdmin) {
      conditions.push(`u.company_code != '*'`);
    }

    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";

    const users = await query<{ user_id: string; user_name: string; count: number }>(
      `SELECT 
         u.user_id, 
         u.user_name, 
         COALESCE(sal.log_count, 0)::int as count
       FROM user_info u
       LEFT JOIN (
         SELECT user_id, COUNT(*) as log_count
         FROM system_audit_log
         GROUP BY user_id
       ) sal ON u.user_id = sal.user_id
       ${whereClause}
       ORDER BY count DESC, u.user_name ASC`,
      params
    );

    res.json({ success: true, data: users });
  } catch (error: any) {
    logger.error("감사 로그 사용자 목록 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "사용자 목록 조회 중 오류가 발생했습니다.",
    });
  }
};

/**
 * 프론트엔드에서 직접 감사 로그 기록 (그룹 복제 등 프론트 오케스트레이션 작업용)
 */
export const createAuditLog = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { action, resourceType, resourceId, resourceName, tableName, summary, changes } = req.body;

    if (!action || !resourceType) {
      res.status(400).json({ success: false, message: "action, resourceType은 필수입니다." });
      return;
    }

    await auditLogService.log({
      companyCode: req.user?.companyCode || "",
      userId: req.user?.userId || "",
      userName: req.user?.userName || "",
      action: action as AuditAction,
      resourceType: resourceType as AuditResourceType,
      resourceId: resourceId || undefined,
      resourceName: resourceName || undefined,
      tableName: tableName || undefined,
      summary: summary || undefined,
      changes: changes || undefined,
      ipAddress: getClientIp(req),
      requestPath: req.originalUrl,
    });

    res.json({ success: true });
  } catch (error: any) {
    logger.error("감사 로그 기록 실패", { error: error.message });
    res.status(500).json({ success: false, message: "감사 로그 기록 실패" });
  }
};
