import {
  Controller,
  Get,
  Post,
  Param,
  Query,
  HttpCode,
  HttpStatus,
  Body,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { SyncService } from './sync.service';
import { RequirePermissions } from '../../../auth/permissions/permissions.decorator';
import { Permission } from '../../../auth/permissions/permissions.enum';
import { AuditLog } from '../../audit/audit.interceptor';

/**
 * DTO for triggering a sync
 */
class TriggerSyncDto {
  fullSync?: boolean;
}

@ApiTags('integrations/sync')
@ApiBearerAuth('JWT-auth')
@Controller('integrations')
export class SyncController {
  constructor(private readonly syncService: SyncService) {}

  @Post(':id/sync')
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  @AuditLog('IntegrationSync', 'TRIGGER')
  @HttpCode(HttpStatus.ACCEPTED)
  @ApiOperation({ summary: 'Trigger a manual sync for an integration' })
  @ApiParam({ name: 'id', description: 'Credential ID' })
  @ApiResponse({
    status: 202,
    description: 'Sync job started',
    schema: {
      type: 'object',
      properties: {
        jobId: { type: 'string' },
        message: { type: 'string' },
      },
    },
  })
  @ApiResponse({ status: 400, description: 'Bad request - sync already running or credential inactive' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Credential not found' })
  triggerSync(
    @Param('id') id: string,
    @Body() body: TriggerSyncDto,
  ) {
    return this.syncService.triggerSync(id, body?.fullSync ?? false);
  }

  @Get(':id/sync/status')
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  @ApiOperation({ summary: 'Get the current sync status for a credential' })
  @ApiParam({ name: 'id', description: 'Credential ID' })
  @ApiResponse({
    status: 200,
    description: 'Current sync status',
    schema: {
      type: 'object',
      properties: {
        credentialId: { type: 'string' },
        type: { type: 'string' },
        name: { type: 'string' },
        isActive: { type: 'boolean' },
        currentStatus: { type: 'string', enum: ['PENDING', 'RUNNING', 'SUCCESS', 'ERROR'] },
        lastSync: { type: 'string', format: 'date-time', nullable: true },
        lastError: { type: 'string', nullable: true },
        isCurrentlyRunning: { type: 'boolean' },
      },
    },
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Credential not found' })
  getSyncStatus(@Param('id') id: string) {
    return this.syncService.getSyncStatus(id);
  }

  @Get(':id/sync/history')
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  @ApiOperation({ summary: 'Get the sync history for a credential' })
  @ApiParam({ name: 'id', description: 'Credential ID' })
  @ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)' })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 20)' })
  @ApiResponse({
    status: 200,
    description: 'Paginated sync history',
    schema: {
      type: 'object',
      properties: {
        data: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              id: { type: 'string' },
              status: { type: 'string' },
              startedAt: { type: 'string', format: 'date-time' },
              completedAt: { type: 'string', format: 'date-time', nullable: true },
              duration: { type: 'number', nullable: true },
              recordsProcessed: { type: 'number', nullable: true },
              error: { type: 'string', nullable: true },
              metadata: { type: 'object', nullable: true },
            },
          },
        },
        meta: {
          type: 'object',
          properties: {
            total: { type: 'number' },
            page: { type: 'number' },
            limit: { type: 'number' },
            totalPages: { type: 'number' },
          },
        },
      },
    },
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Credential not found' })
  getSyncHistory(
    @Param('id') id: string,
    @Query('page') page?: number,
    @Query('limit') limit?: number,
  ) {
    return this.syncService.getSyncHistory(id, page || 1, limit || 20);
  }

  @Get('sync/jobs/:jobId')
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  @ApiOperation({ summary: 'Get status of a specific sync job' })
  @ApiParam({ name: 'jobId', description: 'Sync Job ID' })
  @ApiResponse({
    status: 200,
    description: 'Sync job status',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Sync job not found' })
  getSyncJobStatus(@Param('jobId') jobId: string) {
    return this.syncService.getSyncJobStatus(jobId);
  }
}
