import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Param,
  Body,
  UseGuards,
  ParseIntPipe,
  Query,
} from '@nestjs/common';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { Permissions } from '../auth/permissions.decorator';
import { PermissionsGuard } from '../auth/guards/permissions.guard';
import { DecisionTreesService } from './decision-trees.service';
import { CreateDecisionTreeDto } from './dto/create-decision-tree.dto';
import { UpdateDecisionTreeDto } from './dto/update-decision-tree.dto';
import { SaveGraphDto } from './dto/decision-tree-graph.dto';

@Controller('api/v1/admin/decision-trees')
@UseGuards(JwtAuthGuard, PermissionsGuard)
export class DecisionTreesController {
  constructor(private readonly treesService: DecisionTreesService) {}

  @Post()
  @Permissions('decision_tree.create')
  async create(@Body() dto: CreateDecisionTreeDto) {
    const tree = await this.treesService.create(dto);
    return { success: true, message: 'Decision tree created', data: tree };
  }

  @Get()
  @Permissions('decision_tree.view')
  async findAll(@Query('status') status?: string) {
    const trees = await this.treesService.findAll(status);
    return { success: true, message: 'Success', data: trees };
  }

  @Get(':id')
  @Permissions('decision_tree.view')
  async findById(@Param('id', ParseIntPipe) id: number) {
    const tree = await this.treesService.findById(id);
    if (!tree) return { success: false, message: 'Decision tree not found' };
    return { success: true, message: 'Success', data: tree };
  }

  @Put(':id')
  @Permissions('decision_tree.update')
  async update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateDecisionTreeDto) {
    const tree = await this.treesService.update(id, dto);
    if (!tree) return { success: false, message: 'Decision tree not found' };
    return { success: true, message: 'Decision tree updated', data: tree };
  }

  /** Replaces the entire node/edge graph - the visual builder posts this. */
  @Put(':id/graph')
  @Permissions('decision_tree.update')
  async saveGraph(@Param('id', ParseIntPipe) id: number, @Body() dto: SaveGraphDto) {
    const tree = await this.treesService.saveGraph(id, dto);
    return { success: true, message: 'Decision tree graph saved', data: tree };
  }

  @Post(':id/publish')
  @Permissions('decision_tree.publish')
  async publish(@Param('id', ParseIntPipe) id: number) {
    const tree = await this.treesService.setStatus(id, 'PUBLISHED');
    return { success: true, message: 'Decision tree published', data: tree };
  }

  @Post(':id/archive')
  @Permissions('decision_tree.publish')
  async archive(@Param('id', ParseIntPipe) id: number) {
    const tree = await this.treesService.setStatus(id, 'ARCHIVED');
    return { success: true, message: 'Decision tree archived', data: tree };
  }

  @Delete(':id')
  @Permissions('decision_tree.delete')
  async delete(@Param('id', ParseIntPipe) id: number) {
    const success = await this.treesService.delete(id);
    return {
      success,
      message: success ? 'Decision tree deleted' : 'Decision tree not found',
    };
  }
}
