/**
 * Customers Controller
 * Mecánicas Diesel - ERP Suite
 *
 * REST API endpoints for customer management.
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import { CustomersService } from '../services/customers.service';
import {
  CreateCustomerSchema,
  UpdateCustomerSchema,
  CustomerFiltersSchema,
} from '../customers.dto';

export function createCustomersRouter(dataSource: DataSource): Router {
  const router = Router();
  const service = new CustomersService(dataSource);

  // Helper to extract tenant from request
  const getTenantId = (req: Request): string => {
    return (req as any).tenantId || req.headers['x-tenant-id'] as string;
  };

  const getUserId = (req: Request): string | undefined => {
    return (req as any).user?.id;
  };

  /**
   * POST /api/v1/customers
   * Create a new customer
   */
  router.post('/', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const userId = getUserId(req);
      const dto = CreateCustomerSchema.parse(req.body);

      const customer = await service.create(tenantId, dto, userId);

      res.status(201).json({
        success: true,
        data: customer,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /api/v1/customers
   * List customers with filters and pagination
   */
  router.get('/', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const filters = CustomerFiltersSchema.parse({
        ...req.query,
        page: req.query.page ? parseInt(req.query.page as string, 10) : 1,
        limit: req.query.limit ? parseInt(req.query.limit as string, 10) : 20,
        isActive: req.query.isActive === 'true' ? true : req.query.isActive === 'false' ? false : undefined,
        hasCredit: req.query.hasCredit === 'true',
      });

      const result = await service.findAll(tenantId, filters);

      res.json({
        success: true,
        ...result,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /api/v1/customers/search
   * Quick search for autocomplete
   */
  router.get('/search', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const query = req.query.q as string || '';
      const limit = parseInt(req.query.limit as string, 10) || 10;

      const customers = await service.search(tenantId, query, limit);

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

  /**
   * GET /api/v1/customers/stats
   * Get customer statistics
   */
  router.get('/stats', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const stats = await service.getStats(tenantId);

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

  /**
   * GET /api/v1/customers/:id
   * Get customer by ID
   */
  router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { id } = req.params;

      const customer = await service.findById(tenantId, id);

      if (!customer) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

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

  /**
   * GET /api/v1/customers/email/:email
   * Get customer by email
   */
  router.get('/email/:email', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { email } = req.params;

      const customer = await service.findByEmail(tenantId, decodeURIComponent(email));

      if (!customer) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

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

  /**
   * GET /api/v1/customers/phone/:phone
   * Get customer by phone
   */
  router.get('/phone/:phone', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { phone } = req.params;

      const customer = await service.findByPhone(tenantId, phone);

      if (!customer) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

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

  /**
   * PATCH /api/v1/customers/:id
   * Update customer
   */
  router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { id } = req.params;
      const dto = UpdateCustomerSchema.parse(req.body);

      const customer = await service.update(tenantId, id, dto);

      if (!customer) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

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

  /**
   * DELETE /api/v1/customers/:id
   * Deactivate customer (soft delete)
   */
  router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { id } = req.params;

      const success = await service.deactivate(tenantId, id);

      if (!success) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

      res.json({
        success: true,
        message: 'Customer deactivated',
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /api/v1/customers/:id/activate
   * Reactivate customer
   */
  router.post('/:id/activate', async (req: Request, res: Response, next: NextFunction) => {
    try {
      const tenantId = getTenantId(req);
      const { id } = req.params;

      const success = await service.activate(tenantId, id);

      if (!success) {
        return res.status(404).json({
          success: false,
          error: 'Customer not found',
        });
      }

      res.json({
        success: true,
        message: 'Customer activated',
      });
    } catch (error) {
      next(error);
    }
  });

  return router;
}
