// Re-export new controllers
export { ReportsController } from './reports.controller';
export { DashboardsController } from './dashboards.controller';

// Legacy controller (kept for backwards compatibility)
import { Request, Response, NextFunction, Router } from 'express';
import { LegacyReportsService } from '../services';

export class LegacyReportsController {
  public router: Router;

  constructor(private readonly reportsService: LegacyReportsService) {
    this.router = Router();

    // Sales Reports
    this.router.get('/sales', this.getSalesReport.bind(this));
    this.router.get('/sales/top-products', this.getTopSellingProducts.bind(this));
    this.router.get('/sales/top-customers', this.getTopCustomers.bind(this));

    // Inventory Reports
    this.router.get('/inventory', this.getInventoryReport.bind(this));
    this.router.get('/inventory/movements', this.getStockMovementReport.bind(this));

    // Financial Reports
    this.router.get('/financial', this.getFinancialReport.bind(this));
    this.router.get('/financial/receivables', this.getAccountsReceivable.bind(this));
    this.router.get('/financial/payables', this.getAccountsPayable.bind(this));
  }

  // ==================== Sales Reports ====================

  private async getSalesReport(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { startDate, endDate, partnerId, productId, groupBy } = req.query;

      const start = startDate ? new Date(startDate as string) : new Date(new Date().setDate(new Date().getDate() - 30));
      const end = endDate ? new Date(endDate as string) : new Date();

      const result = await this.reportsService.getSalesReport({
        tenantId,
        startDate: start,
        endDate: end,
        partnerId: partnerId as string,
        productId: productId as string,
        groupBy: groupBy as 'day' | 'week' | 'month' | 'partner' | 'product',
      });

      res.json(result);
    } catch (e) {
      next(e);
    }
  }

  private async getTopSellingProducts(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { startDate, endDate, limit } = req.query;

      const start = startDate ? new Date(startDate as string) : new Date(new Date().setDate(new Date().getDate() - 30));
      const end = endDate ? new Date(endDate as string) : new Date();

      const data = await this.reportsService.getTopSellingProducts(
        tenantId,
        start,
        end,
        limit ? parseInt(limit as string) : 10
      );

      res.json({ data });
    } catch (e) {
      next(e);
    }
  }

  private async getTopCustomers(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { startDate, endDate, limit } = req.query;

      const start = startDate ? new Date(startDate as string) : new Date(new Date().setDate(new Date().getDate() - 30));
      const end = endDate ? new Date(endDate as string) : new Date();

      const data = await this.reportsService.getTopCustomers(
        tenantId,
        start,
        end,
        limit ? parseInt(limit as string) : 10
      );

      res.json({ data });
    } catch (e) {
      next(e);
    }
  }

  // ==================== Inventory Reports ====================

  private async getInventoryReport(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { warehouseId, productId, categoryId, lowStockOnly } = req.query;

      const result = await this.reportsService.getInventoryReport({
        tenantId,
        warehouseId: warehouseId as string,
        productId: productId as string,
        categoryId: categoryId as string,
        lowStockOnly: lowStockOnly === 'true',
      });

      res.json(result);
    } catch (e) {
      next(e);
    }
  }

  private async getStockMovementReport(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { startDate, endDate, warehouseId } = req.query;

      const start = startDate ? new Date(startDate as string) : new Date(new Date().setDate(new Date().getDate() - 30));
      const end = endDate ? new Date(endDate as string) : new Date();

      const data = await this.reportsService.getStockMovementReport(
        tenantId,
        start,
        end,
        warehouseId as string
      );

      res.json({ data });
    } catch (e) {
      next(e);
    }
  }

  // ==================== Financial Reports ====================

  private async getFinancialReport(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const { startDate, endDate, reportType } = req.query;

      const start = startDate ? new Date(startDate as string) : new Date(new Date().setMonth(new Date().getMonth() - 12));
      const end = endDate ? new Date(endDate as string) : new Date();

      const result = await this.reportsService.getFinancialReport({
        tenantId,
        startDate: start,
        endDate: end,
        reportType: (reportType as any) || 'profit_loss',
      });

      res.json(result);
    } catch (e) {
      next(e);
    }
  }

  private async getAccountsReceivable(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const now = new Date();
      const result = await this.reportsService.getFinancialReport({
        tenantId,
        startDate: now,
        endDate: now,
        reportType: 'accounts_receivable',
      });

      res.json(result);
    } catch (e) {
      next(e);
    }
  }

  private async getAccountsPayable(req: Request, res: Response, next: NextFunction) {
    try {
      const tenantId = req.headers['x-tenant-id'] as string;
      if (!tenantId) {
        res.status(400).json({ error: 'Tenant ID required' });
        return;
      }

      const now = new Date();
      const result = await this.reportsService.getFinancialReport({
        tenantId,
        startDate: now,
        endDate: now,
        reportType: 'accounts_payable',
      });

      res.json(result);
    } catch (e) {
      next(e);
    }
  }
}
