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

import { Router, Request, Response } from 'express';
import { DataSource } from 'typeorm';
import { AuthService } from './auth.service';
import {
  loginSchema,
  registerSchema,
  changePasswordSchema,
  refreshTokenSchema,
} from './auth.dto';
import { ZodError } from 'zod';
import { authMiddleware } from '../../shared/middleware/auth.middleware';
import { AuthRequest } from '../../shared/types';

export function createAuthController(dataSource: DataSource): Router {
  const router = Router();
  const authService = new AuthService(dataSource);

  /**
   * POST /api/v1/auth/login
   */
  router.post('/login', async (req: Request, res: Response) => {
    try {
      const dto = loginSchema.parse(req.body);
      const result = await authService.login(dto);

      res.json({
        success: true,
        data: result,
      });
    } 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(401).json({
        success: false,
        error: { message: (error as Error).message, code: 'AUTH_ERROR' },
      });
    }
  });

  /**
   * POST /api/v1/auth/register
   */
  router.post('/register', async (req: Request, res: Response) => {
    try {
      const dto = registerSchema.parse(req.body);
      const tenantId = req.headers['x-tenant-id'] as string | undefined;

      const result = await authService.register(dto, tenantId);

      res.status(201).json({
        success: true,
        data: result,
      });
    } 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: 'REGISTER_ERROR' },
      });
    }
  });

  /**
   * POST /api/v1/auth/logout
   */
  router.post('/logout', authMiddleware, async (req: AuthRequest, res: Response) => {
    try {
      const { refreshToken } = req.body;

      if (!refreshToken) {
        return res.status(400).json({
          success: false,
          error: { message: 'Refresh token requerido', code: 'MISSING_TOKEN' },
        });
      }

      await authService.logout(refreshToken);

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

  /**
   * POST /api/v1/auth/refresh
   */
  router.post('/refresh', async (req: Request, res: Response) => {
    try {
      const dto = refreshTokenSchema.parse(req.body);
      const result = await authService.refresh(dto.refreshToken);

      res.json({
        success: true,
        data: result,
      });
    } 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(401).json({
        success: false,
        error: { message: (error as Error).message, code: 'REFRESH_ERROR' },
      });
    }
  });

  /**
   * GET /api/v1/auth/profile
   */
  router.get('/profile', authMiddleware, async (req: AuthRequest, res: Response) => {
    try {
      const user = await authService.getProfile(req.user!.userId);

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

  /**
   * POST /api/v1/auth/change-password
   */
  router.post('/change-password', authMiddleware, async (req: AuthRequest, res: Response) => {
    try {
      const dto = changePasswordSchema.parse(req.body);
      await authService.changePassword(req.user!.userId, dto);

      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: 'PASSWORD_ERROR' },
      });
    }
  });

  return router;
}
