// https://medium.com/@hxu0407/9-smart-ways-to-replace-if-else-in-javascript-28f82ad6dcb9

// 1. Object Mapping Instead of if-else
function getPrice(user) {
  if (user.type === 'vip') {
    return 'VIP Price';
  } else if (user.type === 'svip') {
    return 'SVIP Price';
  } else if (user.type === 'vvip') {
    return 'VVIP Price';
  } else {
    return 'Regular Price';
  }
}

// better
const priceStrategy = {
  vip: () => 'VIP Price',
  svip: () => 'SVIP Price',
  vvip: () => 'VVIP Price',
  default: () => 'Regular Price'
};

function getPrice(user) {
  return (priceStrategy[user.type] || priceStrategy.default)();
}



// 2. Replace Multiple Conditions with Array.includes
if (status === 'failed' || status === 'error' || status === 'rejected') {
  handleError();
}

// better
const errorStatus = ['failed', 'error', 'rejected'];
if (errorStatus.includes(status)) {
  handleError();
}



// 3. Chained Ternary Operators
let message;
if (score >= 90) {
  message = 'Excellent';
} else if (score >= 80) {
  message = 'Good';
} else if (score >= 60) {
  message = 'Pass';
} else {
  message = 'Fail';
}

// better 
const message =
  score >= 90 ? 'Excellent' :
  score >= 80 ? 'Good' :
  score >= 60 ? 'Pass' :
  'Fail';
  
  
  
// 4. Logical Operators && and ||
// Replacing a simple `if`
user.isAdmin && showAdminPanel();
// Setting default values
const name = user.name || 'unnamed';
// Nullish coalescing
const count = data?.users ?? [];



// 5. Switch-Case with Pattern Matching
const actions = new Map([
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
]);

/*or

const actions = [
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
];
*/

const handleRequest = (type) => {
  const action = [...actions].find(([key]) => key.test(type));
  return action ? action[1]() : handleDefault();
};



// 6. Using Proxy for Conditional Interception
const handler = {
  get: (target, property) => {
    return property in target ? target[property] : target.default;
  }
};

const services = new Proxy({
  admin: () => 'Admin Service',
  user: () => 'User Service',
  default: () => 'Default Service'
}, handler);



// 7. Functional Approach
// Composing conditions
const isAdult = age => age >= 18;
const hasPermission = role => ['admin', 'superuser'].includes(role);
const canAccess = user => isAdult(user.age) && hasPermission(user.role);

// Usage
users.filter(canAccess).forEach(grantAccess);



// 8. State Machine Pattern
const stateMachine = {
  draft: {
    publish: 'published',
    delete: 'deleted'
  },
  published: {
    unpublish: 'draft',
    archive: 'archived'
  },
  archived: {
    restore: 'draft'
  }
};

const changeState = (currentState, action) =>
  stateMachine[currentState]?.[action] || currentState;
  
  
  
// 9. Use Decorators to Handle Conditional Logic
function checkPermission(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args) {
    if (this.user?.hasPermission) {
      return original.apply(this, args);
    }
    throw new Error('No permission');
  };
  return descriptor;
}

class Document {
  @checkPermission
  edit() {
    // Edit the document
  }
}