/**
 * SettingsController - Unified Settings Management Controller
 *
 * REST endpoints for managing settings with hierarchical inheritance.
 * Handles system, plan, tenant settings and user preferences.
 *
 * @module Settings
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import {
  SystemSettingService,
  PlanSettingService,
  TenantSettingService,
  UserPreferenceService,
  SystemSettingFilters,
  TenantSettingFilters,
} from '../services';
import {
  SystemSetting,
  PlanSetting,
  TenantSetting,
  UserPreference,
} from '../entities';
import { AuthMiddleware } from '../../auth/middleware/auth.middleware';
import { AuthService } from '../../auth/services/auth.service';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';

interface ServiceContext {
  tenantId: string;
  userId?: string;
}

export function createSettingsController(dataSource: DataSource): Router {
  const router = Router();

  // Repositories
  const systemSettingRepository = dataSource.getRepository(SystemSetting);
  const planSettingRepository = dataSource.getRepository(PlanSetting);
  const tenantSettingRepository = dataSource.getRepository(TenantSetting);
  const userPreferenceRepository = dataSource.getRepository(UserPreference);
  const userRepository = dataSource.getRepository(User);
  const tenantRepository = dataSource.getRepository(Tenant);
  const refreshTokenRepository = dataSource.getRepository(RefreshToken);

  // Services
  const systemSettingService = new SystemSettingService(systemSettingRepository);
  const planSettingService = new PlanSettingService(planSettingRepository);
  const tenantSettingService = new TenantSettingService(
    tenantSettingRepository,
    systemSettingRepository,
    planSettingRepository
  );
  const userPreferenceService = new UserPreferenceService(userPreferenceRepository);
  const authService = new AuthService(userRepository, tenantRepository, refreshTokenRepository as any);
  const authMiddleware = new AuthMiddleware(authService, dataSource);

  // Helper to create service context
  const getContext = (req: Request): ServiceContext => {
    if (!req.tenantId) {
      throw new Error('Tenant ID is required');
    }
    return {
      tenantId: req.tenantId,
      userId: req.user?.sub,
    };
  };

  // ==================== EFFECTIVE SETTINGS ====================

  /**
   * GET /settings/effective
   * Get all effective settings with inheritance applied
   */
  router.get('/effective', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const planId = req.query.planId as string | undefined;

      const settings = await tenantSettingService.getEffectiveSettings(ctx, planId);

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

  /**
   * GET /settings/effective/:key
   * Get effective value for a specific key
   */
  router.get('/effective/:key', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const planId = req.query.planId as string | undefined;

      const value = await tenantSettingService.getEffectiveValue(ctx, req.params.key, planId);

      if (value === null) {
        res.status(404).json({ error: 'Not Found', message: 'Setting not found' });
        return;
      }

      res.status(200).json({
        success: true,
        data: { key: req.params.key, value },
      });
    } catch (error) {
      next(error);
    }
  });

  // ==================== SYSTEM SETTINGS ====================

  /**
   * GET /settings/system
   * Get system settings (admin only)
   */
  router.get('/system', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: SystemSettingFilters = {};
      if (req.query.category) filters.category = req.query.category as string;
      if (req.query.isPublic !== undefined) filters.isPublic = req.query.isPublic === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await systemSettingService.findWithFilters(filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/system/public
   * Get public system settings (no auth required)
   */
  router.get('/system/public', async (_req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const settings = await systemSettingService.getPublicSettings();
      res.status(200).json({ success: true, data: settings });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/system/categories
   * Get all system setting categories
   */
  router.get('/system/categories', authMiddleware.authenticate, async (_req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const categories = await systemSettingService.getCategories();
      res.status(200).json({ success: true, data: categories });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/system/category/:category
   * Get system settings by category
   */
  router.get('/system/category/:category', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const settings = await systemSettingService.findByCategory(req.params.category);
      res.status(200).json({ success: true, data: settings });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/system/key/:key
   * Get system setting by key
   */
  router.get('/system/key/:key', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const setting = await systemSettingService.findByKey(req.params.key);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'System setting not found' });
        return;
      }

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

  /**
   * POST /settings/system
   * Create system setting (admin only)
   */
  router.post('/system', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { key, value, dataType, category, description, isPublic, isEditable, defaultValue, validationRules } = req.body;

      if (!key || !category) {
        res.status(400).json({ error: 'Bad Request', message: 'key and category are required' });
        return;
      }

      const setting = await systemSettingService.create(ctx, {
        key,
        value,
        dataType,
        category,
        description,
        isPublic,
        isEditable,
        defaultValue,
        validationRules,
      });

      res.status(201).json({ success: true, data: setting });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /settings/system/:id
   * Update system setting
   */
  router.put('/system/:id', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const setting = await systemSettingService.update(ctx, req.params.id, req.body);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'System setting not found' });
        return;
      }

      res.status(200).json({ success: true, data: setting });
    } catch (error) {
      if (error instanceof Error && error.message.includes('not editable')) {
        res.status(403).json({ error: 'Forbidden', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /settings/system/key/:key/value
   * Update system setting value by key
   */
  router.put('/system/key/:key/value', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { value } = req.body;

      if (value === undefined) {
        res.status(400).json({ error: 'Bad Request', message: 'value is required' });
        return;
      }

      const setting = await systemSettingService.updateValueByKey(ctx, req.params.key, value);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'System setting not found' });
        return;
      }

      res.status(200).json({ success: true, data: setting });
    } catch (error) {
      if (error instanceof Error && (error.message.includes('not editable') || error.message.includes('must be'))) {
        res.status(400).json({ error: 'Bad Request', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * POST /settings/system/key/:key/reset
   * Reset system setting to default value
   */
  router.post('/system/key/:key/reset', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const setting = await systemSettingService.resetToDefault(ctx, req.params.key);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'System setting not found or no default value' });
        return;
      }

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

  /**
   * PUT /settings/system/bulk
   * Bulk update system settings
   */
  router.put('/system/bulk', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { settings } = req.body;

      if (!Array.isArray(settings)) {
        res.status(400).json({ error: 'Bad Request', message: 'settings array is required' });
        return;
      }

      const result = await systemSettingService.updateMultiple(ctx, settings);

      res.status(200).json({
        success: true,
        data: result,
        message: `Updated ${result.updated} settings`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /settings/system/:id
   * Delete system setting
   */
  router.delete('/system/:id', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const deleted = await systemSettingService.hardDelete(req.params.id);

      if (!deleted) {
        res.status(404).json({ error: 'Not Found', message: 'System setting not found' });
        return;
      }

      res.status(200).json({ success: true, message: 'System setting deleted' });
    } catch (error) {
      if (error instanceof Error && error.message.includes('cannot be deleted')) {
        res.status(403).json({ error: 'Forbidden', message: error.message });
        return;
      }
      next(error);
    }
  });

  // ==================== PLAN SETTINGS ====================

  /**
   * GET /settings/plan/:planId
   * Get all settings for a plan
   */
  router.get('/plan/:planId', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const settings = await planSettingService.findByPlan(req.params.planId);
      res.status(200).json({ success: true, data: settings });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/plan/:planId/key/:key
   * Get plan setting by plan ID and key
   */
  router.get('/plan/:planId/key/:key', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const setting = await planSettingService.findByPlanAndKey(req.params.planId, req.params.key);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'Plan setting not found' });
        return;
      }

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

  /**
   * POST /settings/plan
   * Create plan setting
   */
  router.post('/plan', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { planId, key, value } = req.body;

      if (!planId || !key) {
        res.status(400).json({ error: 'Bad Request', message: 'planId and key are required' });
        return;
      }

      const setting = await planSettingService.create(ctx, { planId, key, value });
      res.status(201).json({ success: true, data: setting });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /settings/plan/:planId/key/:key
   * Update or create plan setting (upsert)
   */
  router.put('/plan/:planId/key/:key', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { value } = req.body;

      const setting = await planSettingService.upsert(ctx, req.params.planId, req.params.key, value);
      res.status(200).json({ success: true, data: setting });
    } catch (error) {
      next(error);
    }
  });

  /**
   * PUT /settings/plan/:planId/bulk
   * Bulk update plan settings
   */
  router.put('/plan/:planId/bulk', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { settings } = req.body;

      if (!Array.isArray(settings)) {
        res.status(400).json({ error: 'Bad Request', message: 'settings array is required' });
        return;
      }

      const result = await planSettingService.updateMultiple(ctx, req.params.planId, settings);

      res.status(200).json({
        success: true,
        data: result,
        message: `Updated ${result.updated}, created ${result.created} settings`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /settings/plan/:sourcePlanId/copy/:targetPlanId
   * Copy settings from one plan to another
   */
  router.post('/plan/:sourcePlanId/copy/:targetPlanId', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const overwrite = req.query.overwrite === 'true';

      const result = await planSettingService.copyFromPlan(
        ctx,
        req.params.sourcePlanId,
        req.params.targetPlanId,
        overwrite
      );

      res.status(200).json({
        success: true,
        data: result,
        message: `Copied ${result.copied} settings, skipped ${result.skipped}`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /settings/plan/:id
   * Delete plan setting
   */
  router.delete('/plan/:id', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const deleted = await planSettingService.hardDelete(req.params.id);

      if (!deleted) {
        res.status(404).json({ error: 'Not Found', message: 'Plan setting not found' });
        return;
      }

      res.status(200).json({ success: true, message: 'Plan setting deleted' });
    } catch (error) {
      next(error);
    }
  });

  // ==================== TENANT SETTINGS ====================

  /**
   * GET /settings/tenant
   * Get all tenant settings
   */
  router.get('/tenant', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: TenantSettingFilters = {};
      if (req.query.inheritedFrom) filters.inheritedFrom = req.query.inheritedFrom as any;
      if (req.query.isOverridden !== undefined) filters.isOverridden = req.query.isOverridden === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await tenantSettingService.findWithFilters(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/tenant/overridden
   * Get only overridden tenant settings
   */
  router.get('/tenant/overridden', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const settings = await tenantSettingService.getOverriddenSettings(ctx);
      res.status(200).json({ success: true, data: settings });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/tenant/key/:key
   * Get tenant setting by key
   */
  router.get('/tenant/key/:key', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const setting = await tenantSettingService.findByKey(ctx, req.params.key);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'Tenant setting not found' });
        return;
      }

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

  /**
   * POST /settings/tenant
   * Create tenant setting
   */
  router.post('/tenant', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { key, value, inheritedFrom, isOverridden } = req.body;

      if (!key) {
        res.status(400).json({ error: 'Bad Request', message: 'key is required' });
        return;
      }

      const setting = await tenantSettingService.create(ctx, { key, value, inheritedFrom, isOverridden });
      res.status(201).json({ success: true, data: setting });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /settings/tenant/key/:key
   * Update or create tenant setting (upsert)
   */
  router.put('/tenant/key/:key', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { value } = req.body;

      const setting = await tenantSettingService.upsert(ctx, req.params.key, value);
      res.status(200).json({ success: true, data: setting });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /settings/tenant/key/:key/reset
   * Reset tenant setting to inherited value
   */
  router.post('/tenant/key/:key/reset', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const setting = await tenantSettingService.resetToInherited(ctx, req.params.key);

      if (!setting) {
        res.status(404).json({ error: 'Not Found', message: 'Tenant setting not found' });
        return;
      }

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

  /**
   * PUT /settings/tenant/bulk
   * Bulk update tenant settings
   */
  router.put('/tenant/bulk', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { settings } = req.body;

      if (!Array.isArray(settings)) {
        res.status(400).json({ error: 'Bad Request', message: 'settings array is required' });
        return;
      }

      const result = await tenantSettingService.updateMultiple(ctx, settings);

      res.status(200).json({
        success: true,
        data: result,
        message: `Updated ${result.updated}, created ${result.created} settings`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /settings/tenant/initialize/:planId
   * Initialize tenant settings from plan defaults
   */
  router.post('/tenant/initialize/:planId', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const initialized = await tenantSettingService.initializeFromPlan(ctx, req.params.planId);

      res.status(200).json({
        success: true,
        data: { initialized },
        message: `Initialized ${initialized} settings from plan`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /settings/tenant/:id
   * Delete tenant setting
   */
  router.delete('/tenant/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const deleted = await tenantSettingService.hardDelete(ctx, req.params.id);

      if (!deleted) {
        res.status(404).json({ error: 'Not Found', message: 'Tenant setting not found' });
        return;
      }

      res.status(200).json({ success: true, message: 'Tenant setting deleted' });
    } catch (error) {
      next(error);
    }
  });

  // ==================== USER PREFERENCES ====================

  /**
   * GET /settings/preferences
   * Get current user's preferences
   */
  router.get('/preferences', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const preferences = await userPreferenceService.getUserPreferencesWithDefaults(req.user.sub);
      res.status(200).json({ success: true, data: preferences });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/preferences/raw
   * Get current user's preferences without defaults
   */
  router.get('/preferences/raw', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const preferences = await userPreferenceService.findByUser(req.user.sub);
      res.status(200).json({ success: true, data: preferences });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /settings/preferences/:key
   * Get specific preference for current user
   */
  router.get('/preferences/:key', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const preference = await userPreferenceService.findByUserAndKey(req.user.sub, req.params.key);

      if (!preference) {
        res.status(404).json({ error: 'Not Found', message: 'Preference not found' });
        return;
      }

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

  /**
   * PUT /settings/preferences/:key
   * Update or create preference for current user
   */
  router.put('/preferences/:key', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const { value } = req.body;
      const preference = await userPreferenceService.upsert(req.user.sub, req.params.key, value);
      res.status(200).json({ success: true, data: preference });
    } catch (error) {
      next(error);
    }
  });

  /**
   * PUT /settings/preferences
   * Bulk update preferences for current user
   */
  router.put('/preferences', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const { preferences } = req.body;

      if (!Array.isArray(preferences)) {
        res.status(400).json({ error: 'Bad Request', message: 'preferences array is required' });
        return;
      }

      const result = await userPreferenceService.updateMultiple(req.user.sub, preferences);

      res.status(200).json({
        success: true,
        data: result,
        message: `Updated ${result.updated}, created ${result.created} preferences`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /settings/preferences/:key/reset
   * Reset preference to default value
   */
  router.post('/preferences/:key/reset', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const preference = await userPreferenceService.resetToDefault(req.user.sub, req.params.key);

      if (!preference) {
        res.status(404).json({ error: 'Not Found', message: 'No default value for this preference' });
        return;
      }

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

  /**
   * POST /settings/preferences/reset-all
   * Reset all preferences to defaults
   */
  router.post('/preferences/reset-all', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const count = await userPreferenceService.resetAllToDefaults(req.user.sub);

      res.status(200).json({
        success: true,
        data: { reset: count },
        message: `Reset ${count} preferences to defaults`,
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /settings/preferences/:key
   * Delete a specific preference
   */
  router.delete('/preferences/:key', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user?.sub) {
        res.status(401).json({ error: 'Unauthorized', message: 'User ID required' });
        return;
      }

      const preference = await userPreferenceService.findByUserAndKey(req.user.sub, req.params.key);

      if (!preference) {
        res.status(404).json({ error: 'Not Found', message: 'Preference not found' });
        return;
      }

      await userPreferenceService.hardDelete(preference.id);
      res.status(200).json({ success: true, message: 'Preference deleted' });
    } catch (error) {
      next(error);
    }
  });

  // ==================== ADMIN: USER PREFERENCES MANAGEMENT ====================

  /**
   * GET /settings/admin/preferences/user/:userId
   * Get preferences for a specific user (admin only)
   */
  router.get('/admin/preferences/user/:userId', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const preferences = await userPreferenceService.findByUser(req.params.userId);
      res.status(200).json({ success: true, data: preferences });
    } catch (error) {
      next(error);
    }
  });

  /**
   * PUT /settings/admin/preferences/user/:userId/:key
   * Update preference for a specific user (admin only)
   */
  router.put('/admin/preferences/user/:userId/:key', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const { value } = req.body;
      const preference = await userPreferenceService.upsert(req.params.userId, req.params.key, value);
      res.status(200).json({ success: true, data: preference });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /settings/admin/preferences/user/:userId
   * Delete all preferences for a user (admin only)
   */
  router.delete('/admin/preferences/user/:userId', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const deleted = await userPreferenceService.deleteByUser(req.params.userId);
      res.status(200).json({
        success: true,
        data: { deleted },
        message: `Deleted ${deleted} preferences`,
      });
    } catch (error) {
      next(error);
    }
  });

  return router;
}

export default createSettingsController;
