/**
 * Compliance Export Router
 * tRPC procedures for exporting activity logs and audit trails
 */

import { router, adminProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { getAdminActivityLogger, AdminActivity } from "../adminActivityLogger.ts";

export const complianceExportRouter = router({
  /**
   * Export activity logs as CSV
   */
  exportActivityLogsCSV: adminProcedure
    .input(
      z.object({
        startDate: z.date(),
        endDate: z.date(),
        adminId: z.number().optional(),
        actionTypes: z.array(z.string()).optional(),
        status: z.array(z.enum(["success", "failure", "warning"])).optional(),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();

        // Get filtered activities
        const activities = logger.getActivities({
          startDate: input.startDate,
          endDate: input.endDate,
          adminId: input.adminId,
          action: input.actionTypes as any,
          status: input.status as any,
        });

        // Generate CSV
        const csv = logger.exportActivitiesAsCSV({
          startDate: input.startDate,
          endDate: input.endDate,
          adminId: input.adminId,
          action: input.actionTypes as any,
          status: input.status as any,
        });

        return {
          success: true,
          csv,
          filename: `compliance_audit_${new Date().toISOString().split("T")[0]}.csv`,
          count: activities.length,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Export activity logs as JSON
   */
  exportActivityLogsJSON: adminProcedure
    .input(
      z.object({
        startDate: z.date(),
        endDate: z.date(),
        adminId: z.number().optional(),
        actionTypes: z.array(z.string()).optional(),
        status: z.array(z.enum(["success", "failure", "warning"])).optional(),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();

        // Get filtered activities
        const activities = logger.getActivities({
          startDate: input.startDate,
          endDate: input.endDate,
          adminId: input.adminId,
          action: input.actionTypes as any,
          status: input.status as any,
        });

        // Generate JSON
        const json = logger.exportActivitiesAsJSON({
          startDate: input.startDate,
          endDate: input.endDate,
          adminId: input.adminId,
          action: input.actionTypes as any,
          status: input.status as any,
        });

        return {
          success: true,
          json,
          filename: `compliance_audit_${new Date().toISOString().split("T")[0]}.json`,
          count: activities.length,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Get suspicious activities for investigation
   */
  getSuspiciousActivities: adminProcedure
    .input(
      z.object({
        limit: z.number().default(50),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();
        const suspicious = logger.getSuspiciousActivities().slice(-input.limit);

        return {
          success: true,
          activities: suspicious,
          count: suspicious.length,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Get admin activity summary for compliance report
   */
  getActivitySummary: adminProcedure
    .input(
      z.object({
        startDate: z.date(),
        endDate: z.date(),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();

        // Get activities in range
        const activities = logger.getActivities({
          startDate: input.startDate,
          endDate: input.endDate,
        });

        // Calculate statistics
        const stats = logger.getStatistics();

        // Group by admin
        const byAdmin: Record<number, number> = {};
        activities.forEach((a) => {
          byAdmin[a.adminId] = (byAdmin[a.adminId] || 0) + 1;
        });

        // Group by action
        const byAction: Record<string, number> = {};
        activities.forEach((a) => {
          byAction[a.action] = (byAction[a.action] || 0) + 1;
        });

        return {
          success: true,
          summary: {
            period: {
              start: input.startDate,
              end: input.endDate,
            },
            totalActivities: activities.length,
            uniqueAdmins: Object.keys(byAdmin).length,
            statistics: stats,
            topAdmins: Object.entries(byAdmin)
              .sort(([, a], [, b]) => b - a)
              .slice(0, 10)
              .map(([adminId, count]) => ({
                adminId: parseInt(adminId),
                count,
              })),
            topActions: Object.entries(byAction)
              .sort(([, a], [, b]) => b - a)
              .slice(0, 10)
              .map(([action, count]) => ({
                action,
                count,
              })),
          },
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Generate compliance report for auditors
   */
  generateComplianceReport: adminProcedure
    .input(
      z.object({
        startDate: z.date(),
        endDate: z.date(),
        includeDetails: z.boolean().default(false),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();

        // Get activities
        const activities = logger.getActivities({
          startDate: input.startDate,
          endDate: input.endDate,
        });

        // Get summary
        const stats = logger.getStatistics();

        // Build report
        const report = {
          reportId: `compliance_${Date.now()}`,
          generatedAt: new Date(),
          generatedBy: ctx.user.id,
          period: {
            start: input.startDate,
            end: input.endDate,
          },
          summary: {
            totalActivities: activities.length,
            uniqueAdmins: stats.uniqueAdmins,
            successfulActions: stats.activitiesByStatus.success || 0,
            failedActions: stats.activitiesByStatus.failure || 0,
            warningActions: stats.activitiesByStatus.warning || 0,
            criticalSeverity: stats.activitiesBySeverity.critical || 0,
            highSeverity: stats.activitiesBySeverity.high || 0,
          },
          actionBreakdown: stats.activitiesByAction,
          severityBreakdown: stats.activitiesBySeverity,
          statusBreakdown: stats.activitiesByStatus,
          details: input.includeDetails ? activities : undefined,
        };

        return {
          success: true,
          report,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Get activity logs for specific admin
   */
  getAdminActivityLogs: adminProcedure
    .input(
      z.object({
        targetAdminId: z.number(),
        limit: z.number().default(100),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();
        const activities = logger.getActivitiesByAdmin(input.targetAdminId, input.limit);

        return {
          success: true,
          activities,
          count: activities.length,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Search activities by criteria
   */
  searchActivities: adminProcedure
    .input(
      z.object({
        query: z.string().optional(),
        adminId: z.number().optional(),
        actionType: z.string().optional(),
        status: z.enum(["success", "failure", "warning"]).optional(),
        severity: z.enum(["low", "medium", "high", "critical"]).optional(),
        startDate: z.date().optional(),
        endDate: z.date().optional(),
        limit: z.number().default(50),
      })
    )
    .query(async ({ input, ctx }) => {
      try {
        const logger = getAdminActivityLogger();

        // Get all activities matching filters
        let activities = logger.getActivities({
          adminId: input.adminId,
          action: input.actionType ? [input.actionType as any] : undefined,
          status: input.status ? [input.status] : undefined,
          severity: input.severity ? [input.severity] : undefined,
          startDate: input.startDate,
          endDate: input.endDate,
        });

        // Filter by query if provided
        if (input.query) {
          const query = input.query.toLowerCase();
          activities = activities.filter(
            (a) =>
              a.description.toLowerCase().includes(query) ||
              a.adminEmail.toLowerCase().includes(query) ||
              JSON.stringify(a.details).toLowerCase().includes(query)
          );
        }

        // Limit results
        activities = activities.slice(-input.limit);

        return {
          success: true,
          activities,
          count: activities.length,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Clear old activities (admin only)
   */
  clearOldActivities: adminProcedure
    .input(
      z.object({
        olderThanDays: z.number().min(30).max(365),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // Only allow super admins
        if (ctx.user.role !== "admin") {
          throw new TRPCError({
            code: "FORBIDDEN",
            message: "Only admins can clear activity logs",
          });
        }

        const logger = getAdminActivityLogger();
        const cleared = logger.clearOldActivities(input.olderThanDays);

        return {
          success: true,
          cleared,
          message: `Cleared ${cleared} activities older than ${input.olderThanDays} days`,
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),
});
