/**
 * Torre Controller
 * API endpoints para gestión de torres/edificios
 *
 * @module Construction (MAI-002)
 * @prefix /api/v1/torres
 */

import { Router, Request, Response, NextFunction } from 'express';
import { TorreService, CreateTorreDto, UpdateTorreDto } from '../services/torre.service';

const router = Router();
const torreService = new TorreService(null as any);

/**
 * GET /api/v1/torres
 * Lista todas las torres del tenant
 */
router.get('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { etapaId, status, search, page, limit } = req.query;

    const result = await torreService.findAll(
      { tenantId },
      {
        etapaId: etapaId as string,
        status: status as string,
        search: search as string,
        page: page ? Number(page) : undefined,
        limit: limit ? Number(limit) : undefined,
      },
    );

    return res.json({
      success: true,
      data: result.data,
      total: result.total,
      page: result.page,
      limit: result.limit,
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/torres/statistics
 * Estadísticas de torres
 */
router.get('/statistics', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const { etapaId } = req.query;
    const stats = await torreService.getStatistics({ tenantId }, etapaId as string);

    return res.json({ success: true, data: stats });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/torres/by-etapa/:etapaId
 * Torres por etapa
 */
router.get('/by-etapa/:etapaId', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const data = await torreService.findByEtapa({ tenantId }, req.params.etapaId);
    return res.json({ success: true, data, count: data.length });
  } catch (error) {
    return next(error);
  }
});

/**
 * GET /api/v1/torres/:id
 * Obtiene una torre por ID
 */
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const torre = await torreService.findById({ tenantId }, req.params.id);
    if (!torre) {
      return res.status(404).json({ error: 'Torre no encontrada' });
    }

    return res.json({ success: true, data: torre });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/torres
 * Crea una nueva torre
 */
router.post('/', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const userId = (req as any).user?.id;
    const dto: CreateTorreDto = req.body;

    if (!dto.etapaId || !dto.code || !dto.name) {
      return res.status(400).json({ error: 'etapaId, code y name son requeridos' });
    }

    const torre = await torreService.create({ tenantId, userId }, dto);
    return res.status(201).json({ success: true, data: torre });
  } catch (error: any) {
    if (error.message?.includes('already exists')) {
      return res.status(409).json({ error: error.message });
    }
    return next(error);
  }
});

/**
 * PATCH /api/v1/torres/:id
 * Actualiza una torre
 */
router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const userId = (req as any).user?.id;
    const dto: UpdateTorreDto = req.body;

    const torre = await torreService.update({ tenantId, userId }, req.params.id, dto);
    if (!torre) {
      return res.status(404).json({ error: 'Torre no encontrada' });
    }

    return res.json({ success: true, data: torre });
  } catch (error) {
    return next(error);
  }
});

/**
 * PATCH /api/v1/torres/:id/status
 * Actualiza el estado de una torre
 */
router.patch('/:id/status', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const userId = (req as any).user?.id;
    const { status } = req.body;

    if (!status) {
      return res.status(400).json({ error: 'status es requerido' });
    }

    const torre = await torreService.updateStatus({ tenantId, userId }, req.params.id, status);
    if (!torre) {
      return res.status(404).json({ error: 'Torre no encontrada' });
    }

    return res.json({ success: true, data: torre, message: 'Estado actualizado' });
  } catch (error) {
    return next(error);
  }
});

/**
 * POST /api/v1/torres/:id/recalculate-units
 * Recalcula el total de unidades de una torre
 */
router.post('/:id/recalculate-units', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const userId = (req as any).user?.id;
    const torre = await torreService.updateUnitCount({ tenantId, userId }, req.params.id);

    if (!torre) {
      return res.status(404).json({ error: 'Torre no encontrada' });
    }

    return res.json({ success: true, data: torre, message: 'Unidades recalculadas' });
  } catch (error) {
    return next(error);
  }
});

/**
 * DELETE /api/v1/torres/:id
 * Elimina una torre (soft delete)
 */
router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'X-Tenant-Id header required' });
    }

    const userId = (req as any).user?.id;
    const deleted = await torreService.softDelete({ tenantId, userId }, req.params.id);

    if (!deleted) {
      return res.status(404).json({ error: 'Torre no encontrada' });
    }

    return res.json({ success: true, message: 'Torre eliminada' });
  } catch (error) {
    return next(error);
  }
});

export default router;
