const {Op}=require("sequelize"),db=require("../../models"),money=require("../pricing/money");const fault=(m,c,s=400)=>Object.assign(new Error(m),{code:c,status:s}); async function getAvailableMethods({address,subtotal,currency="LKR",at=new Date()}){const regions=await db.ShippingZoneRegion.findAll({where:{country_code:String(address.country_code).toUpperCase(),[Op.and]:[{[Op.or]:[{province:null},{province:address.province}]},{[Op.or]:[{district:null},{district:address.district}]}]},order:[["province","DESC"],["district","DESC"]]});if(!regions.length)throw fault("Destination is not supported","UNSUPPORTED_DESTINATION",409);const zone=await db.ShippingZone.findOne({where:{id:regions[0].shipping_zone_id,status:"ACTIVE"}});if(!zone)throw fault("Destination is not supported","UNSUPPORTED_DESTINATION",409);const rates=await db.ShippingRate.findAll({where:{shipping_zone_id:zone.id,currency,status:"ACTIVE",[Op.and]:[{[Op.or]:[{starts_at:null},{starts_at:{[Op.lte]:at}}]},{[Op.or]:[{ends_at:null},{ends_at:{[Op.gt]:at}}]}]},include:[{model:db.ShippingMethod,as:"method",where:{status:"ACTIVE"}}]});return rates.filter(r=>(!r.minimum_subtotal||money.parse(subtotal)>=money.parse(r.minimum_subtotal))&&(!r.maximum_subtotal||money.parse(subtotal)<=money.parse(r.maximum_subtotal))).map(r=>{const free=Boolean(r.free_shipping_threshold&&money.parse(subtotal)>=money.parse(r.free_shipping_threshold));return {shippingRateId:r.id,methodId:r.method.id,code:r.method.code,name:r.method.name,amount:free?"0.00":String(r.base_amount),freeShippingApplied:free,estimatedMinDays:r.method.estimated_min_days,estimatedMaxDays:r.method.estimated_max_days,zone:{code:zone.code,name:zone.name},dutyMode:zone.duty_mode};});} module.exports={getAvailableMethods};