import {
  Controller,
  Post,
  Get,
  Patch,
  Body,
  Param,
  Query,
  UseGuards,
  HttpCode,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { WorkflowsService } from './services/workflows.service';
import { CreateWorkflowDto } from './dto/create-workflow.dto';
import { UpdateWorkflowDto } from './dto/update-workflow.dto';
import { Roles } from '../../common/decorators/roles.decorator';
import { RolesGuard } from '../../common/guards/roles.guard';
import { UserRole } from '../../common/enums';

@ApiTags('Workflows')
@Controller('workflows')
@ApiBearerAuth('BearerAuth')
@UseGuards(AuthGuard('jwt'), RolesGuard)
export class WorkflowsController {
  private readonly logger = new Logger(WorkflowsController.name);

  constructor(private readonly workflowsService: WorkflowsService) {}

  @Post()
  @HttpCode(HttpStatus.CREATED)
  @Roles(UserRole.ADMIN)
  @ApiOperation({
    summary: 'Create new workflow',
    description: 'Create a new workflow configuration for license processing',
  })
  @ApiResponse({ status: 201, description: 'Workflow created successfully' })
  @ApiResponse({ status: 400, description: 'Invalid workflow definition' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - Admin only' })
  async create(@Body() dto: CreateWorkflowDto) {
    this.logger.debug(`Creating new workflow: ${dto.name}`);
    return this.workflowsService.create(dto);
  }

  @Get()
  @ApiOperation({
    summary: 'List all workflows',
    description: 'Get all workflow configurations with optional active filter',
  })
  @ApiQuery({
    name: 'isActive',
    required: false,
    type: Boolean,
    description: 'Filter by active status',
  })
  @ApiResponse({ status: 200, description: 'List of workflows' })
  async findAll(@Query('isActive') isActive?: string) {
    const active = isActive !== undefined ? isActive === 'true' : undefined;
    const workflows = await this.workflowsService.findAll(active);
    return { data: workflows, total: workflows.length };
  }

  @Get(':id')
  @ApiOperation({
    summary: 'Get workflow by ID',
    description: 'Get a specific workflow configuration by ID',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Workflow details' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async findById(@Param('id') id: string) {
    return this.workflowsService.findById(id);
  }

  @Get('type/:workflowType')
  @ApiOperation({
    summary: 'Get workflow by type',
    description: 'Get the active workflow for a specific workflow type',
  })
  @ApiParam({ name: 'workflowType', description: 'Workflow type identifier' })
  @ApiResponse({ status: 200, description: 'Workflow details' })
  @ApiResponse({ status: 404, description: 'No active workflow found for type' })
  async findByType(@Param('workflowType') workflowType: string) {
    return this.workflowsService.findByType(workflowType);
  }

  @Get(':id/preview')
  @ApiOperation({
    summary: 'Preview workflow structure',
    description: 'Get a preview of the workflow stages and departments',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Workflow preview' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async preview(@Param('id') id: string) {
    return this.workflowsService.preview(id);
  }

  @Post(':id/validate')
  @HttpCode(HttpStatus.OK)
  @Roles(UserRole.ADMIN)
  @ApiOperation({
    summary: 'Validate workflow definition',
    description: 'Validate the definition of an existing workflow',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Validation result' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async validate(@Param('id') id: string) {
    const workflow = await this.workflowsService.findById(id);
    return this.workflowsService.validateDefinition(workflow.definition as any);
  }

  @Patch(':id')
  @Roles(UserRole.ADMIN)
  @ApiOperation({
    summary: 'Update workflow',
    description: 'Update an existing workflow configuration',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Workflow updated successfully' })
  @ApiResponse({ status: 400, description: 'Invalid update or workflow is inactive' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async update(@Param('id') id: string, @Body() dto: UpdateWorkflowDto) {
    this.logger.debug(`Updating workflow: ${id}`);
    return this.workflowsService.update(id, dto);
  }

  @Post(':id/deactivate')
  @HttpCode(HttpStatus.OK)
  @Roles(UserRole.ADMIN)
  @ApiOperation({
    summary: 'Deactivate workflow',
    description: 'Deactivate a workflow so it is no longer used for new requests',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Workflow deactivated' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async deactivate(@Param('id') id: string) {
    this.logger.debug(`Deactivating workflow: ${id}`);
    await this.workflowsService.deactivate(id);
    return { message: 'Workflow deactivated successfully' };
  }

  @Post(':id/activate')
  @HttpCode(HttpStatus.OK)
  @Roles(UserRole.ADMIN)
  @ApiOperation({
    summary: 'Activate workflow',
    description: 'Re-activate a previously deactivated workflow',
  })
  @ApiParam({ name: 'id', description: 'Workflow ID (UUID)' })
  @ApiResponse({ status: 200, description: 'Workflow activated' })
  @ApiResponse({ status: 404, description: 'Workflow not found' })
  async activate(@Param('id') id: string) {
    this.logger.debug(`Activating workflow: ${id}`);
    await this.workflowsService.activate(id);
    return { message: 'Workflow activated successfully' };
  }
}
