import { Request, Response } from 'express';
import { OmnichannelCommunicationService } from '../../services/integration/OmnichannelCommunicationService';
import { OmnichannelMarketingService } from '../../services/marketing/OmnichannelMarketingService';
import { UnifiedFulfillmentService } from '../../services/integration/UnifiedFulfillmentService';
import { StoreCreationService } from '../../services/platform/StoreCreationService';
import { CrossBorderIntegrationService } from '../../services/integration/CrossBorderIntegrationService';
import { AuditService } from '../../services/utils/AuditService';
import { logger } from '../../utils/logger';

export class OmnichannelController {
  static async aggregateMessages(req: Request, res: Response) {
    const { channels } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const messages = await OmnichannelCommunicationService.aggregateMessages(tenantId, channels);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'COMMUNICATION',
        action: 'AGGREGATE_MESSAGES',
        resourceType: 'message',
        metadata: { channelCount: channels.length, messageCount: messages.length },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: messages });
    } catch (err: any) {
      logger.error(`[OmnichannelController] Aggregate messages failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async autoReply(req: Request, res: Response) {
    const { customerId, question, context } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const reply = await OmnichannelCommunicationService.autoReply(tenantId, customerId, question, context);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'COMMUNICATION',
        action: 'AUTO_REPLY',
        resourceType: 'customer',
        resourceId: customerId,
        metadata: { question },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: { reply } });
    } catch (err: any) {
      logger.error(`[OmnichannelController] Auto reply failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async createTeamTask(req: Request, res: Response) {
    const { assignedTo, customerId, taskType, priority, description, dueDate } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const task = await OmnichannelCommunicationService.createTeamTask(tenantId, {
        tenantId,
        assignedTo,
        customerId,
        taskType,
        priority,
        status: 'pending',
        description,
        dueDate: dueDate ? new Date(dueDate) : undefined,
      });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'COMMUNICATION',
        action: 'CREATE_TEAM_TASK',
        resourceType: 'task',
        resourceId: task.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: task });
    } catch (err: any) {
      logger.error(`[OmnichannelController] Create team task failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async updateCustomerProfile(req: Request, res: Response) {
    const customerId = req.params.customerId as string;
    const { channels, tags, preferences } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const profile = await OmnichannelCommunicationService.updateCustomerProfile(tenantId, customerId, {
        channels,
        tags,
        preferences,
      });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'COMMUNICATION',
        action: 'UPDATE_CUSTOMER_PROFILE',
        resourceType: 'customer',
        resourceId: customerId,
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: profile });
    } catch (err: any) {
      logger.error(`[OmnichannelController] Update customer profile failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async translateMessage(req: Request, res: Response) {
    const { content, targetLanguage } = req.body;
    const { tenantId } = (req as any).traceContext;

    try {
      const translated = await OmnichannelCommunicationService.translateMessage(tenantId, content, targetLanguage);
      res.json({ success: true, data: { translated } });
    } catch (err: any) {
      logger.error(`[OmnichannelController] Translate message failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }
}

export class MarketingController {
  static async integrateChannels(req: Request, res: Response) {
    const { channels } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const integrated = await OmnichannelMarketingService.integrateChannels(tenantId, channels);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'MARKETING',
        action: 'INTEGRATE_CHANNELS',
        resourceType: 'channel',
        metadata: { channelCount: integrated.length },
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: integrated });
    } catch (err: any) {
      logger.error(`[MarketingController] Integrate channels failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async createAutomation(req: Request, res: Response) {
    const { name, trigger, actions, status } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const rule = await OmnichannelMarketingService.createAutomation(tenantId, {
        tenantId,
        name,
        trigger,
        actions,
        status: status || 'active',
      });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'MARKETING',
        action: 'CREATE_AUTOMATION',
        resourceType: 'automation',
        resourceId: rule.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: rule });
    } catch (err: any) {
      logger.error(`[MarketingController] Create automation failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async analyzeCampaign(req: Request, res: Response) {
    const campaignId = req.params.campaignId as string;
    const { start, end } = req.query;
    const { tenantId } = (req as any).traceContext;

    try {
      const startStr = Array.isArray(start) ? start[0] : start;
      const endStr = Array.isArray(end) ? end[0] : end;
      
      const metrics = await OmnichannelMarketingService.analyzeCampaignEffect(
        tenantId,
        campaignId,
        { start: new Date(startStr as string), end: new Date(endStr as string) }
      );

      res.json({ success: true, data: metrics });
    } catch (err: any) {
      logger.error(`[MarketingController] Analyze campaign failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async runABTest(req: Request, res: Response) {
    const { name, variants, trafficSplit } = req.body;
    const { tenantId, shopId, taskId, traceId } = (req as any).traceContext;

    try {
      const result = await OmnichannelMarketingService.runABTest(tenantId, {
        name,
        variants,
        trafficSplit,
        shopId,
        taskId,
        traceId,
        businessType: 'TOC',
      });

      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[MarketingController] Run A/B test failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }
}

export class FulfillmentController {
  static async unifyOrders(req: Request, res: Response) {
    const { platformOrders } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const unified = await UnifiedFulfillmentService.unifyOrders(tenantId, platformOrders);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FULFILLMENT',
        action: 'UNIFY_ORDERS',
        resourceType: 'order',
        metadata: { orderCount: unified.length },
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: unified });
    } catch (err: any) {
      logger.error(`[FulfillmentController] Unify orders failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async routeOrder(req: Request, res: Response) {
    const orderId = req.params.orderId as string;
    const { inventoryData } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const route = await UnifiedFulfillmentService.routeOrder(tenantId, orderId, inventoryData);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FULFILLMENT',
        action: 'ROUTE_ORDER',
        resourceType: 'order',
        resourceId: orderId,
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: route });
    } catch (err: any) {
      logger.error(`[FulfillmentController] Route order failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async manageFulfillment(req: Request, res: Response) {
    const orderId = req.params.orderId as string;
    const { action, params } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const status = await UnifiedFulfillmentService.manageFulfillment(tenantId, orderId, action, params);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FULFILLMENT',
        action: 'MANAGE_FULFILLMENT',
        resourceType: 'order',
        resourceId: orderId,
        metadata: { action },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: status });
    } catch (err: any) {
      logger.error(`[FulfillmentController] Manage fulfillment failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async syncStatus(req: Request, res: Response) {
    const orderId = req.params.orderId as string;
    const { status } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const result = await UnifiedFulfillmentService.syncStatus(tenantId, orderId, status);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FULFILLMENT',
        action: 'SYNC_STATUS',
        resourceType: 'order',
        resourceId: orderId,
        metadata: { status },
        result: result.success ? 'success' : 'failed',
        source: 'console',
      });

      res.json({ success: result.success, data: result });
    } catch (err: any) {
      logger.error(`[FulfillmentController] Sync status failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }
}

export class StoreCreationController {
  static async createTemplate(req: Request, res: Response) {
    const { name, category, designParams } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const template = await StoreCreationService.createTemplate(tenantId, { name, category, designParams });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'STORE_CREATION',
        action: 'CREATE_TEMPLATE',
        resourceType: 'template',
        resourceId: template.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: template });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Create template failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async updatePageComponents(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const pageId = req.params.pageId as string;
    const { components } = req.body;

    try {
      const page = await StoreCreationService.updatePageComponents(websiteId, pageId, components);
      res.json({ success: true, data: page });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Update page components failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async adaptResponsiveLayout(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const pageId = req.params.pageId as string;
    const { deviceType } = req.query;

    try {
      const deviceTypeStr = Array.isArray(deviceType) ? deviceType[0] : deviceType;
      
      const components = await StoreCreationService.adaptResponsiveLayout(
        websiteId,
        pageId,
        deviceTypeStr as 'desktop' | 'tablet' | 'mobile'
      );
      res.json({ success: true, data: components });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Adapt responsive layout failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async setupMultilingual(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { languages } = req.body;

    try {
      const config = await StoreCreationService.setupMultilingual(websiteId, languages);
      res.status(201).json({ success: true, data: config });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Setup multilingual failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async createBrand(req: Request, res: Response) {
    const { name, designAssets } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const brand = await StoreCreationService.createBrand(tenantId, { name, designAssets });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'STORE_CREATION',
        action: 'CREATE_BRAND',
        resourceType: 'brand',
        resourceId: brand.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: brand });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Create brand failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async manageContent(req: Request, res: Response) {
    const brandId = req.params.brandId as string;
    const { type, content } = req.body;

    try {
      const result = await StoreCreationService.manageContent(brandId, { type, content });
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Manage content failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateEcommerce(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { features } = req.body;

    try {
      const result = await StoreCreationService.integrateEcommerce(websiteId, features);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Integrate ecommerce failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateMarketing(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { params } = req.body;

    try {
      const result = await StoreCreationService.integrateMarketing(websiteId, params);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Integrate marketing failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async configureShipping(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { params } = req.body;

    try {
      const result = await StoreCreationService.configureShipping(websiteId, params);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Configure shipping failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async generateAnalytics(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { metrics, timeRange } = req.body;

    try {
      const report = await StoreCreationService.generateAnalytics(websiteId, { metrics, timeRange });
      res.json({ success: true, data: report });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Generate analytics failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async optimizeSEO(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { params } = req.body;

    try {
      const result = await StoreCreationService.optimizeSEO(websiteId, params);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Optimize SEO failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateSocialMedia(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { accounts } = req.body;

    try {
      const result = await StoreCreationService.integrateSocialMedia(websiteId, accounts);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Integrate social media failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async manageContentMarketing(req: Request, res: Response) {
    const websiteId = req.params.websiteId as string;
    const { contentData } = req.body;

    try {
      const result = await StoreCreationService.manageContentMarketing(websiteId, contentData);
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Manage content marketing failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async spreadBrandStory(req: Request, res: Response) {
    const brandId = req.params.brandId as string;
    const { channels, schedule } = req.body;

    try {
      const result = await StoreCreationService.spreadBrandStory(brandId, { channels, schedule });
      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[StoreCreationController] Spread brand story failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }
}

export class CrossBorderController {
  static async integrateSellbrite(req: Request, res: Response) {
    const { credentials } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const integration = await CrossBorderIntegrationService.integrateSellbrite(tenantId, credentials);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'INTEGRATE_SELLBRITE',
        resourceType: 'integration',
        resourceId: integration.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: integration });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Integrate Sellbrite failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateShoplazza(req: Request, res: Response) {
    const { credentials } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const integration = await CrossBorderIntegrationService.integrateShoplazza(tenantId, credentials);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'INTEGRATE_SHOPLAZZA',
        resourceType: 'integration',
        resourceId: integration.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: integration });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Integrate Shoplazza failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateSaleSmartly(req: Request, res: Response) {
    const { credentials } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const integration = await CrossBorderIntegrationService.integrateSaleSmartly(tenantId, credentials);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'INTEGRATE_SALESMARTLY',
        resourceType: 'integration',
        resourceId: integration.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: integration });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Integrate SaleSmartly failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async syncInventory(req: Request, res: Response) {
    const { inventoryData } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const records = await CrossBorderIntegrationService.syncInventoryToPlatforms(tenantId, inventoryData);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'SYNC_INVENTORY',
        resourceType: 'inventory',
        metadata: { recordCount: records.length },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: records });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Sync inventory failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async integrateMarketing(req: Request, res: Response) {
    const { platform, campaignId, config } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const integration = await CrossBorderIntegrationService.integrateMarketing(tenantId, {
        platform,
        campaignId,
        config,
      });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'INTEGRATE_MARKETING',
        resourceType: 'marketing',
        resourceId: integration.id,
        result: 'success',
        source: 'console',
      });

      res.status(201).json({ success: true, data: integration });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Integrate marketing failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async getIntegrationStatus(req: Request, res: Response) {
    const { platform } = req.query;
    const { tenantId } = (req as any).traceContext;

    try {
      const platformStr = Array.isArray(platform) ? platform[0] : platform;
      
      const integrations = await CrossBorderIntegrationService.getIntegrationStatus(
        tenantId,
        platformStr as string
      );
      res.json({ success: true, data: integrations });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Get integration status failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }

  static async disconnectPlatform(req: Request, res: Response) {
    const platform = req.params.platform as string;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const result = await CrossBorderIntegrationService.disconnectPlatform(tenantId, platform);

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'CROSS_BORDER',
        action: 'DISCONNECT_PLATFORM',
        resourceType: 'integration',
        metadata: { platform },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true, data: result });
    } catch (err: any) {
      logger.error(`[CrossBorderController] Disconnect platform failed: ${err.message}`);
      res.status(500).json({ success: false, error: err.message });
    }
  }
}
