using Microsoft.AspNetCore.Mvc; namespace Distribution.Features.Scheme; [ApiController] [Route("api/schemes")] public class SchemeController(SchemeService service) : ControllerBase { [HttpGet] public async Task GetAll([FromQuery] Guid? regionId) => Ok(await service.GetAllAsync(regionId)); [HttpGet("{id:guid}")] public async Task GetById(Guid id) { var result = await service.GetByIdAsync(id); return result is null ? NotFound() : Ok(result); } [HttpPost] public async Task Create(CreateSchemeRequest request, CancellationToken ct) { try { var result = await service.CreateAsync(request, ct); return CreatedAtAction(nameof(GetById), new { id = result.Id }, result); } catch (InvalidOperationException ex) { return BadRequest(new { error = ex.Message }); } } [HttpPut("{id:guid}")] public async Task Update(Guid id, UpdateSchemeRequest request, CancellationToken ct) { try { var result = await service.UpdateAsync(id, request, ct); return result is null ? NotFound() : Ok(result); } catch (InvalidOperationException ex) { return BadRequest(new { error = ex.Message }); } } [HttpDelete("{id:guid}")] public async Task Delete(Guid id, CancellationToken ct) { var deleted = await service.DeleteAsync(id, ct); return deleted ? NoContent() : NotFound(); } [HttpPut("{id:guid}/free-goods-rule")] public async Task SetFreeGoodsRule(Guid id, SetFreeGoodsRuleRequest request, CancellationToken ct) { try { var result = await service.SetFreeGoodsRuleAsync(id, request, ct); return result is null ? NotFound() : Ok(result); } catch (InvalidOperationException ex) { return Conflict(new { error = ex.Message }); } } [HttpDelete("{id:guid}/free-goods-rule")] public async Task ClearFreeGoodsRule(Guid id, CancellationToken ct) { var result = await service.ClearFreeGoodsRuleAsync(id, ct); return result is null ? NotFound() : Ok(result); } [HttpPut("{id:guid}/bundle-components/{itemId:guid}")] public async Task UpsertBundleComponent(Guid id, Guid itemId, UpsertBundleComponentRequest request, CancellationToken ct) { try { var result = await service.UpsertBundleComponentAsync(id, itemId, request, ct); return result is null ? NotFound() : Ok(result); } catch (InvalidOperationException ex) { return Conflict(new { error = ex.Message }); } } [HttpDelete("{id:guid}/bundle-components/{itemId:guid}")] public async Task RemoveBundleComponent(Guid id, Guid itemId, CancellationToken ct) { var result = await service.RemoveBundleComponentAsync(id, itemId, ct); return result is null ? NotFound() : Ok(result); } [HttpGet("eligible")] public async Task GetEligible([FromQuery] Guid storeId, [FromQuery] Guid orderId) { var result = await service.EvaluateEligibilityAsync(storeId, orderId); return result is null ? NotFound() : Ok(result); } [HttpGet("{id:guid}/spend")] public async Task GetSpend(Guid id) { var result = await service.GetSpendAsync(id); return result is null ? NotFound() : Ok(result); } [HttpGet("{id:guid}/roi")] public async Task GetROI(Guid id) { var result = await service.GetROIAsync(id); return result is null ? NotFound() : Ok(result); } } [ApiController] [Route("api/orders")] public class SchemeOrderController(SchemeService service) : ControllerBase { [HttpPost("{id:guid}/apply-scheme")] public async Task ApplyScheme(Guid id, ApplySchemeRequest request, CancellationToken ct) { try { var result = await service.ApplySchemeAsync(id, request.SchemeId, ct); return result is null ? NotFound() : Ok(result); } catch (InvalidOperationException ex) { return Conflict(new { error = ex.Message }); } } }