import { Request, Response } from 'express';
import { AfterSalesService, AfterSalesContext } from '../../services/order/AfterSalesService';

export class AfterSalesController {
  static async initTables(req: Request, res: Response): Promise<void> {
    try {
      await AfterSalesService.initTables();
      res.json({ success: true, message: 'After-sales tables initialized' });
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async createRequest(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const { orderId, type, reason, description, items, customerId, customerName, customerEmail } = req.body;

      const result = await AfterSalesService.createRequest(context, {
        orderId,
        type,
        reason,
        description,
        items,
        customerId,
        customerName,
        customerEmail
      });

      res.status(201).json(result);
    } catch (error: any) {
      res.status(400).json({ success: false, error: error.message });
    }
  }

  static async getRequests(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const { status, type, orderId, page, pageSize } = req.query;

      const result = await AfterSalesService.getRequests(context.tenantId, {
        status: status as any,
        type: type as any,
        orderId: orderId as string,
        page: page ? parseInt(page as string) : 1,
        pageSize: pageSize ? parseInt(pageSize as string) : 20
      });

      res.json(result);
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async getRequestById(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const id = req.params.id as string;

      const request = await AfterSalesService.getRequestById(context.tenantId, id);

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

      res.json(request);
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async approveRequest(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const id = req.params.id as string;
      const { approved, approvedBy, rejectedReason, refundAmount } = req.body;

      const result = await AfterSalesService.approveRequest(context, id, {
        approved,
        approvedBy,
        rejectedReason,
        refundAmount
      });

      res.json(result);
    } catch (error: any) {
      res.status(400).json({ success: false, error: error.message });
    }
  }

  static async processRefund(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const refundId = req.params.refundId as string;
      const { transactionId, refundMethod } = req.body;

      const result = await AfterSalesService.processRefund(context, refundId, {
        transactionId,
        refundMethod
      });

      res.json(result);
    } catch (error: any) {
      res.status(400).json({ success: false, error: error.message });
    }
  }

  static async getRefundById(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const refundId = req.params.refundId as string;

      const refund = await AfterSalesService.getRefundById(context.tenantId, refundId);

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

      res.json(refund);
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async processReturn(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const returnId = req.params.returnId as string;
      const { action, ...actionData } = req.body;

      const result = await AfterSalesService.processReturn(context, returnId, action, actionData);

      res.json(result);
    } catch (error: any) {
      res.status(400).json({ success: false, error: error.message });
    }
  }

  static async getReturnById(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const returnId = req.params.returnId as string;

      const returnRecord = await AfterSalesService.getReturnById(context.tenantId, returnId);

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

      res.json(returnRecord);
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async closeRequest(req: Request, res: Response): Promise<void> {
    try {
      const context = AfterSalesController.getContext(req);
      const id = req.params.id as string;
      const { reason } = req.body;

      const result = await AfterSalesService.closeRequest(context, id, reason);

      res.json(result);
    } catch (error: any) {
      res.status(400).json({ success: false, error: error.message });
    }
  }

  private static getContext(req: Request): AfterSalesContext {
    return {
      tenantId: req.headers['x-tenant-id'] as string || 'default',
      shopId: req.headers['x-shop-id'] as string || 'default',
      taskId: req.headers['x-task-id'] as string || `task-${Date.now()}`,
      traceId: req.headers['x-trace-id'] as string || `trace-${Date.now()}`,
      businessType: (req.headers['x-business-type'] as 'TOC' | 'TOB') || 'TOC'
    };
  }
}
