/**
 * Users Controller
 * Mecánicas Diesel - ERP Suite
 */

import { Router, Response } from 'express';
import { DataSource } from 'typeorm';
import { ZodError } from 'zod';
import { UsersService } from './users.service';
import {
  createUserSchema,
  updateUserSchema,
  resetPasswordSchema,
  UserFilters,
} from './users.dto';
import { authMiddleware } from '../../shared/middleware/auth.middleware';
import { AuthRequest } from '../../shared/types';
import { UserRole } from '../auth/entities/user.entity';

export function createUsersController(dataSource: DataSource): Router {
  const router = Router();
  const usersService = new UsersService(dataSource);

  // All routes require authentication
  router.use(authMiddleware);

  /**
   * Middleware to check admin permissions
   */
  const requireAdmin = (req: AuthRequest, res: Response, next: Function) => {
    if (req.user?.role !== UserRole.ADMIN && req.user?.role !== UserRole.JEFE_TALLER) {
      return res.status(403).json({
        success: false,
        error: { message: 'Acceso denegado. Se requiere rol de admin o jefe de taller', code: 'FORBIDDEN' },
      });
    }
    next();
  };

  /**
   * GET /api/v1/users
   * List users with filters and pagination
   */
  router.get('/', async (req: AuthRequest, res: Response) => {
    try {
      const filters: UserFilters = {
        role: req.query.role as UserRole,
        isActive: req.query.isActive === 'true' ? true : req.query.isActive === 'false' ? false : undefined,
        search: req.query.search as string,
      };

      const pagination = {
        page: parseInt(req.query.page as string, 10) || 1,
        limit: Math.min(parseInt(req.query.limit as string, 10) || 20, 100),
      };

      const result = await usersService.findAll(req.tenantId!, filters, pagination);

      res.json({
        success: true,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: { message: (error as Error).message, code: 'SERVER_ERROR' },
      });
    }
  });

  /**
   * GET /api/v1/users/:id
   * Get a single user by ID
   */
  router.get('/:id', async (req: AuthRequest, res: Response) => {
    try {
      const user = await usersService.findById(req.tenantId!, req.params.id);

      if (!user) {
        return res.status(404).json({
          success: false,
          error: { message: 'Usuario no encontrado', code: 'NOT_FOUND' },
        });
      }

      res.json({
        success: true,
        data: user,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: { message: (error as Error).message, code: 'SERVER_ERROR' },
      });
    }
  });

  /**
   * POST /api/v1/users
   * Create new user (admin only)
   */
  router.post('/', requireAdmin, async (req: AuthRequest, res: Response) => {
    try {
      const dto = createUserSchema.parse(req.body);
      const user = await usersService.create(req.tenantId!, dto);

      res.status(201).json({
        success: true,
        data: user,
      });
    } catch (error) {
      if (error instanceof ZodError) {
        return res.status(400).json({
          success: false,
          error: { message: 'Datos inválidos', code: 'VALIDATION_ERROR', details: error.errors },
        });
      }
      res.status(400).json({
        success: false,
        error: { message: (error as Error).message, code: 'CREATE_ERROR' },
      });
    }
  });

  /**
   * PATCH /api/v1/users/:id
   * Update user
   */
  router.patch('/:id', requireAdmin, async (req: AuthRequest, res: Response) => {
    try {
      const dto = updateUserSchema.parse(req.body);
      const user = await usersService.update(req.tenantId!, req.params.id, dto);

      if (!user) {
        return res.status(404).json({
          success: false,
          error: { message: 'Usuario no encontrado', code: 'NOT_FOUND' },
        });
      }

      res.json({
        success: true,
        data: user,
      });
    } catch (error) {
      if (error instanceof ZodError) {
        return res.status(400).json({
          success: false,
          error: { message: 'Datos inválidos', code: 'VALIDATION_ERROR', details: error.errors },
        });
      }
      res.status(400).json({
        success: false,
        error: { message: (error as Error).message, code: 'UPDATE_ERROR' },
      });
    }
  });

  /**
   * DELETE /api/v1/users/:id
   * Soft delete user (admin only)
   */
  router.delete('/:id', requireAdmin, async (req: AuthRequest, res: Response) => {
    try {
      const success = await usersService.delete(req.tenantId!, req.params.id);

      if (!success) {
        return res.status(404).json({
          success: false,
          error: { message: 'Usuario no encontrado', code: 'NOT_FOUND' },
        });
      }

      res.json({
        success: true,
        data: null,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: { message: (error as Error).message, code: 'DELETE_ERROR' },
      });
    }
  });

  /**
   * PATCH /api/v1/users/:id/reset-password
   * Reset user password (admin only)
   */
  router.patch('/:id/reset-password', requireAdmin, async (req: AuthRequest, res: Response) => {
    try {
      const dto = resetPasswordSchema.parse(req.body);
      const success = await usersService.resetPassword(req.tenantId!, req.params.id, dto);

      if (!success) {
        return res.status(404).json({
          success: false,
          error: { message: 'Usuario no encontrado', code: 'NOT_FOUND' },
        });
      }

      res.json({
        success: true,
        data: null,
      });
    } catch (error) {
      if (error instanceof ZodError) {
        return res.status(400).json({
          success: false,
          error: { message: 'Datos inválidos', code: 'VALIDATION_ERROR', details: error.errors },
        });
      }
      res.status(400).json({
        success: false,
        error: { message: (error as Error).message, code: 'RESET_PASSWORD_ERROR' },
      });
    }
  });

  return router;
}
