import {
  Controller, Get, Post, Put, Delete,
  Body, Param, UseGuards, NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Team } from './entities/team.entity';
import { Agency } from './entities/agency.entity';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../common/guards/roles.guard';
import { Roles, Role } from '../common/decorators/roles.decorator';
import { User } from '../users/entities/user.entity';

@Controller('teams')
@UseGuards(JwtAuthGuard)
export class TeamsController {
  constructor(
    @InjectRepository(Team)
    private readonly teamRepo: Repository<Team>,
    @InjectRepository(Agency)
    private readonly agencyRepo: Repository<Agency>,
    @InjectRepository(User)
    private readonly userRepo: Repository<User>,
  ) {}

  // ─── Équipes ────────────────────────────────────────────────────────────────

  @Get()
  findAll() {
    return this.teamRepo.find({
      relations: ['agency', 'manager'],
      order: { name: 'ASC' },
    });
  }

  @Post()
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR, Role.AGENCY_MANAGER)
  async createTeam(@Body() body: {
    name: string;
    agency_id?: number;
    manager_id?: number;
    min_presence?: number;
  }) {
    if (!body.name?.trim()) {
      throw new BadRequestException("Le nom de l'équipe est requis");
    }

    const team = this.teamRepo.create({
      name: body.name.trim(),
      min_presence: body.min_presence ?? 1,
    });

    if (body.agency_id) {
      const agency = await this.agencyRepo.findOne({ where: { id: body.agency_id } });
      if (agency) team.agency = agency;
    }
    if (body.manager_id) {
      const manager = await this.userRepo.findOne({ where: { id: body.manager_id } });
      if (manager) team.manager = manager;
    }

    return this.teamRepo.save(team);
  }

  @Put(':id')
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR, Role.AGENCY_MANAGER)
  async updateTeam(
    @Param('id') id: string,
    @Body() body: {
      name?: string;
      agency_id?: number | null;
      manager_id?: number | null;
      min_presence?: number;
    },
  ) {
    const team = await this.teamRepo.findOne({
      where: { id: +id },
      relations: ['agency', 'manager'],
    });
    if (!team) throw new NotFoundException(`Équipe #${id} introuvable`);

    if (body.name !== undefined)         team.name         = body.name.trim();
    if (body.min_presence !== undefined) team.min_presence = body.min_presence;

    if (body.agency_id !== undefined) {
      if (body.agency_id) {
        const agency = await this.agencyRepo.findOne({ where: { id: body.agency_id } });
        team.agency = agency ?? null;
      } else {
        team.agency = null;
      }
    }
    if (body.manager_id !== undefined) {
      if (body.manager_id) {
        const manager = await this.userRepo.findOne({ where: { id: body.manager_id } });
        team.manager = manager ?? null;
      } else {
        team.manager = null;
      }
    }

    return this.teamRepo.save(team);
  }

  @Delete(':id')
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR)
  async deleteTeam(@Param('id') id: string) {
    const team = await this.teamRepo.findOne({ where: { id: +id } });
    if (!team) throw new NotFoundException(`Équipe #${id} introuvable`);
    await this.teamRepo.remove(team);
    return { success: true, message: 'Équipe supprimée' };
  }

  // ─── Agences ────────────────────────────────────────────────────────────────

  @Get('agencies')
  findAllAgencies() {
    return this.agencyRepo.find({
      relations: ['manager'],
      order: { name: 'ASC' },
    });
  }

  @Post('agencies')
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR, Role.AGENCY_MANAGER)
  async createAgency(@Body() body: {
    name: string;
    country?: string;
    manager_id?: number;
  }) {
    if (!body.name?.trim()) {
      throw new BadRequestException("Le nom de l'agence est requis");
    }

    const agency = this.agencyRepo.create({
      name: body.name.trim(),
      country: body.country ?? 'Madagascar',
    });

    if (body.manager_id) {
      const manager = await this.userRepo.findOne({ where: { id: body.manager_id } });
      if (manager) agency.manager = manager;
    }

    return this.agencyRepo.save(agency);
  }

  @Put('agencies/:id')
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR, Role.AGENCY_MANAGER)
  async updateAgency(
    @Param('id') id: string,
    @Body() body: {
      name?: string;
      country?: string;
      manager_id?: number | null;
    },
  ) {
    const agency = await this.agencyRepo.findOne({
      where: { id: +id },
      relations: ['manager'],
    });
    if (!agency) throw new NotFoundException(`Agence #${id} introuvable`);

    if (body.name !== undefined)    agency.name    = body.name.trim();
    if (body.country !== undefined) agency.country = body.country;

    if (body.manager_id !== undefined) {
      if (body.manager_id) {
        const manager = await this.userRepo.findOne({ where: { id: body.manager_id } });
        agency.manager = manager ?? null;
      } else {
        agency.manager = null;
      }
    }

    return this.agencyRepo.save(agency);
  }

  @Delete('agencies/:id')
  @UseGuards(RolesGuard)
  @Roles(Role.DIRECTOR)
  async deleteAgency(@Param('id') id: string) {
    const agency = await this.agencyRepo.findOne({ where: { id: +id } });
    if (!agency) throw new NotFoundException(`Agence #${id} introuvable`);
    await this.agencyRepo.remove(agency);
    return { success: true, message: 'Agence supprimée' };
  }
}