import { Get, Path, Query, Request, Response, Route, Security, SuccessResponse, Tags, Delete } from 'tsoa';
import { ValidationError } from '../middleware/errorHandler';
import { auditService } from '../services/audit.service';
import { AuditAction } from '@prisma/client';
import {
    ListAuditLogsResponse,
    AuditLogResponse,
    AuditLogStats,
} from '../types/audit.types';

@Route('api/admin/audit-logs')
@Tags('Admin/AuditLogs')
export class AuditController {

    /**
     * ดึงรายการ audit logs ทั้งหมด
     * Get all audit logs with filters and pagination
     * @param userId - กรองตาม user ID
     * @param action - กรองตาม action type
     * @param entityType - กรองตาม entity type (Course, User, Lesson, etc.)
     * @param entityId - กรองตาม entity ID
     * @param startDate - วันที่เริ่มต้น (ISO format)
     * @param endDate - วันที่สิ้นสุด (ISO format)
     * @param page - หน้าที่ต้องการ
     * @param limit - จำนวนรายการต่อหน้า
     */
    @Get('')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'Audit logs retrieved successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    public async getAuditLogs(
        @Request() request: any,
        @Query() userId?: number,
        @Query() action?: AuditAction,
        @Query() entityType?: string,
        @Query() entityId?: number,
        @Query() startDate?: string,
        @Query() endDate?: string,
        @Query() page?: number,
        @Query() limit?: number
    ): Promise<ListAuditLogsResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        return await auditService.getLogs({
            userId,
            action,
            entityType,
            entityId,
            startDate: startDate ? new Date(startDate) : undefined,
            endDate: endDate ? new Date(endDate) : undefined,
            page: page || 1,
            limit: limit || 50,
        });
    }

    /**
     * ดึง audit log by ID
     * Get audit log detail by ID
     * @param logId - รหัส audit log
     */
    @Get('{logId}')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'Audit log retrieved successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    @Response('404', 'Audit log not found')
    public async getAuditLogById(
        @Request() request: any,
        @Path() logId: number
    ): Promise<AuditLogResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        const log = await auditService.getLogById(logId);
        if (!log) {
            throw new ValidationError('Audit log not found');
        }
        return log;
    }

    /**
     * ดึงสถิติ audit logs สำหรับ dashboard
     * Get audit log statistics for admin dashboard
     */
    @Get('stats/summary')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'Audit stats retrieved successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    public async getAuditStats(@Request() request: any): Promise<AuditLogStats> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        return await auditService.getStats();
    }

    /**
     * ดึง history ของ entity เฉพาะ
     * Get audit history for a specific entity
     * @param entityType - ประเภท entity (Course, User, Lesson, etc.)
     * @param entityId - รหัส entity
     */
    @Get('entity/{entityType}/{entityId}')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'Entity history retrieved successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    public async getEntityHistory(
        @Request() request: any,
        @Path() entityType: string,
        @Path() entityId: number
    ): Promise<AuditLogResponse[]> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        return await auditService.getEntityHistory(entityType, entityId);
    }

    /**
     * ดึง activity ของ user เฉพาะ
     * Get activity logs for a specific user
     * @param userId - รหัส user
     * @param limit - จำนวนรายการ
     */
    @Get('user/{userId}/activity')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'User activity retrieved successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    public async getUserActivity(
        @Request() request: any,
        @Path() userId: number,
        @Query() limit?: number
    ): Promise<AuditLogResponse[]> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        return await auditService.getUserActivity(userId, limit || 50);
    }

    /**
     * ลบ audit logs เก่า (maintenance)
     * Delete old audit logs for maintenance
     * @param days - ลบ logs ที่เก่ากว่ากี่วัน
     */
    @Delete('cleanup')
    @Security('jwt', ['admin'])
    @SuccessResponse('200', 'Old logs deleted successfully')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden - Admin only')
    public async deleteOldLogs(
        @Request() request: any,
        @Query() days: number = 90
    ): Promise<{ deleted: number; message: string }> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) {
            throw new ValidationError('No token provided');
        }

        if (days < 30) {
            throw new ValidationError('Cannot delete logs newer than 30 days');
        }

        const deleted = await auditService.deleteOldLogs(days);
        return {
            deleted,
            message: `Deleted ${deleted} audit logs older than ${days} days`,
        };
    }
}
