import { Router, Request, Response } from 'express';
import { SaasTenantService } from '../../services/tenant/SaasTenantService';
import { TenantDomainMiddleware } from '../../middleware/TenantDomainMiddleware';
import { logger } from '../../utils/logger';

const router = Router();

router.use(TenantDomainMiddleware.resolveTenant);

router.get('/tenants', async (req: Request, res: Response) => {
  try {
    const filters: any = {};
    
    if (req.query.status) {
      filters.status = req.query.status as string;
    }
    if (req.query.plan) {
      filters.plan = req.query.plan as string;
    }
    if (req.query.type) {
      filters.type = req.query.type as string;
    }

    const tenants = await SaasTenantService.listTenants(filters);
    
    res.json({ success: true, data: tenants });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error listing tenants:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId', async (req: Request, res: Response) => {
  try {
    const tenant = await SaasTenantService.getTenant(req.params.tenantId as string);
    
    if (!tenant) {
      return res.status(404).json({ error: 'Tenant not found' });
    }
    
    res.json({ success: true, data: tenant });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant:', error);
    res.status(500).json({ error: error.message });
  }
});

router.post('/tenants', async (req: Request, res: Response) => {
  try {
    const tenant = await SaasTenantService.createTenant(req.body);
    
    res.status(201).json({ success: true, data: tenant });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error creating tenant:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/domains', async (req: Request, res: Response) => {
  try {
    const domains = await SaasTenantService.getTenantDomains(req.params.tenantId as string);
    
    res.json({ success: true, data: domains });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant domains:', error);
    res.status(500).json({ error: error.message });
  }
});

router.post('/tenants/:tenantId/domains', async (req: Request, res: Response) => {
  try {
    const { domain, type } = req.body;
    
    if (!domain) {
      return res.status(400).json({ error: 'Domain is required' });
    }
    
    const tenantDomain = await SaasTenantService.addDomain(
      req.params.tenantId as string,
      domain,
      type || 'SUBDOMAIN'
    );
    
    res.status(201).json({ success: true, data: tenantDomain });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error adding domain:', error);
    res.status(500).json({ error: error.message });
  }
});

router.post('/domains/:domainId/verify', async (req: Request, res: Response) => {
  try {
    const domain = await SaasTenantService.verifyDomain(req.params.domainId as string);
    
    res.json({ success: true, data: domain });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error verifying domain:', error);
    res.status(500).json({ error: error.message });
  }
});

router.post('/domains/:domainId/primary', async (req: Request, res: Response) => {
  try {
    await SaasTenantService.setPrimaryDomain(req.params.domainId as string);
    
    res.json({ success: true, message: 'Primary domain set successfully' });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error setting primary domain:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/users', async (req: Request, res: Response) => {
  try {
    const users = await SaasTenantService.getTenantUsers(req.params.tenantId as string);
    
    res.json({ success: true, data: users });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant users:', error);
    res.status(500).json({ error: error.message });
  }
});

router.post('/tenants/:tenantId/users', async (req: Request, res: Response) => {
  try {
    const { userId, role, permissions } = req.body;
    
    if (!userId) {
      return res.status(400).json({ error: 'User ID is required' });
    }
    
    const tenantUser = await SaasTenantService.addUser(
      req.params.tenantId as string,
      userId,
      role || 'OPERATOR',
      permissions || []
    );
    
    res.status(201).json({ success: true, data: tenantUser });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error adding user:', error);
    res.status(500).json({ error: error.message });
  }
});

router.put('/tenants/:tenantId/users/:userId', async (req: Request, res: Response) => {
  try {
    const { role, permissions } = req.body;
    
    if (!role) {
      return res.status(400).json({ error: 'Role is required' });
    }
    
    const tenantUser = await SaasTenantService.updateUserRole(
      req.params.tenantId as string,
      req.params.userId as string,
      role,
      permissions || []
    );
    
    res.json({ success: true, data: tenantUser });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error updating user role:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/users/:userId/tenants', async (req: Request, res: Response) => {
  try {
    const tenants = await SaasTenantService.getUserTenants(req.params.userId as string);
    
    res.json({ success: true, data: tenants });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting user tenants:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/settings', async (req: Request, res: Response) => {
  try {
    const category = req.query.category as string;
    const settings = await SaasTenantService.getSettings(req.params.tenantId as string, category);
    
    res.json({ success: true, data: settings });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant settings:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/settings/:key', async (req: Request, res: Response) => {
  try {
    const tenantId = Array.isArray(req.params.tenantId) ? req.params.tenantId[0] : req.params.tenantId;
    const key = Array.isArray(req.params.key) ? req.params.key[0] : req.params.key;
    const value = await SaasTenantService.getSetting(tenantId, key);
    
    if (value === null) {
      return res.status(404).json({ error: 'Setting not found' });
    }
    
    res.json({ success: true, data: { key, value } });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant setting:', error);
    res.status(500).json({ error: error.message });
  }
});

router.put('/tenants/:tenantId/settings/:key', async (req: Request, res: Response) => {
  try {
    const { value, category } = req.body;
    
    if (value === undefined) {
      return res.status(400).json({ error: 'Value is required' });
    }
    
    const tenantId = Array.isArray(req.params.tenantId) ? req.params.tenantId[0] : req.params.tenantId;
    const key = Array.isArray(req.params.key) ? req.params.key[0] : req.params.key;
    
    await SaasTenantService.setSetting(
      tenantId,
      key,
      value,
      category || 'general'
    );
    
    res.json({ success: true, message: 'Setting updated successfully' });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error setting tenant setting:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/current-tenant', (req: Request, res: Response) => {
  if (!req.tenant) {
    return res.status(404).json({ error: 'No tenant found for current request' });
  }
  
  res.json({ success: true, data: req.tenant });
});

router.put('/tenants/:tenantId', async (req: Request, res: Response) => {
  try {
    const tenant = await SaasTenantService.updateTenant(req.params.tenantId as string, req.body);
    
    res.json({ success: true, data: tenant });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error updating tenant:', error);
    res.status(500).json({ error: error.message });
  }
});

router.delete('/tenants/:tenantId', async (req: Request, res: Response) => {
  try {
    await SaasTenantService.deleteTenant(req.params.tenantId as string);
    
    res.json({ success: true, message: 'Tenant deleted successfully' });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error deleting tenant:', error);
    res.status(500).json({ error: error.message });
  }
});

router.put('/tenants/:tenantId/status', async (req: Request, res: Response) => {
  try {
    const { status } = req.body;
    
    if (!status) {
      return res.status(400).json({ error: 'Status is required' });
    }
    
    const tenant = await SaasTenantService.updateTenantStatus(req.params.tenantId as string, status);
    
    res.json({ success: true, data: tenant });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error updating tenant status:', error);
    res.status(500).json({ error: error.message });
  }
});

router.delete('/domains/:domainId', async (req: Request, res: Response) => {
  try {
    await SaasTenantService.deleteDomain(req.params.domainId as string);
    
    res.json({ success: true, message: 'Domain deleted successfully' });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error deleting domain:', error);
    res.status(500).json({ error: error.message });
  }
});

router.delete('/tenants/:tenantId/users/:userId', async (req: Request, res: Response) => {
  try {
    await SaasTenantService.removeUser(req.params.tenantId as string, req.params.userId as string);
    
    res.json({ success: true, message: 'User removed successfully' });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error removing user:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/stats', async (req: Request, res: Response) => {
  try {
    const stats = await SaasTenantService.getStats();
    
    res.json({ success: true, data: stats });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting stats:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/usage', async (req: Request, res: Response) => {
  try {
    const usage = await SaasTenantService.getUsage(req.params.tenantId as string);
    
    res.json({ success: true, data: usage });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting tenant usage:', error);
    res.status(500).json({ error: error.message });
  }
});

router.get('/tenants/:tenantId/logs', async (req: Request, res: Response) => {
  try {
    const logs = await SaasTenantService.getOperationLogs(req.params.tenantId as string);
    
    res.json({ success: true, data: logs });
  } catch (error: any) {
    logger.error('[SaasTenantAPI] Error getting operation logs:', error);
    res.status(500).json({ error: error.message });
  }
});

export default router;