using Fast.Web.Models;
using Microsoft.AspNetCore.OData.Routing.Controllers;

namespace Fast.Web.Controllers;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class SalesTaxRateController(MyDbContext context) : ODataController
{
    private readonly MyDbContext db = context;
    private readonly AuthorizationHelper authHelper = new(Main.IsAuthenticationEnabled);

    [Permission("Sales Tax Rate", PermissionType.View)]
    [Route("/odata/GetSalesTaxRateItems")]
    public IActionResult GetItems(ODataQueryOptions<SalesTaxRateListItem> queryOptions, bool isExport)
    {
        var itemsQueryable = GetItemsInternal();
        var items = (queryOptions.ApplyTo(itemsQueryable) as IEnumerable<SalesTaxRateListItem>)?.ToList();

        if (isExport)
            return File(Util.Excel.GetExportFileStream(items), "application/octet-stream");
        else
            return Ok(items);
    }

    [Permission("Sales Tax Rate", PermissionType.View)]
    [Route("[action]")]
    public IQueryable<SalesTaxRateListItem> GetItemsInternal()
    {
        IQueryable<SalesTaxRateListItem>? itemsQueryable = null;

        itemsQueryable = (
            from q in db.SalesTaxRates
            select new SalesTaxRateListItem
            {
                SalesTaxRateId = q.Id,
                CountyName = q.County.Name ?? "",
                StateName = q.County.State.Name ?? "",
                InactiveDate = q.InactiveDate,
                Rate = q.Rate
            }
        ).AsNoTracking();

        return itemsQueryable;
    }

    [Permission("Sales Tax Rate", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetRequiredData()
    {
        var hasModifyPermission = await authHelper.IsAuthorizedAsync(User, "Sales Tax Rate", PermissionType.Modify);
        var states = await DataHelper.GetTerritoriesAsync();
        var counties = await db.Counties.Select(x => new { countyId = x.Id, CountyName = x.Name, StateName = x.State.Name, x.StateId }).ToListAsync();
        var result = new { hasModifyPermission, states, counties };
        return Ok(result);
    }

    [Permission("Sales Tax Rate", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetDetail(int id)
    {
        var detail = await (
            from q in db.SalesTaxRates
            where q.Id == id
            select new SalesTaxRateDetail
            {
                SalesTaxRateId = q.Id,
                CountyId = q.CountyId,
                StateId = q.County.StateId,
                InactiveDate = q.InactiveDate,
                Rate = q.Rate
            }
        ).AsNoTracking().FirstAsync();

        return Ok(detail);
    }

    public enum SaveType
    {
        New = 1,
        Normal = 2
    }

    [Permission("Sales Tax Rate", PermissionType.Modify)]
    [Route("[action]")]
    public async Task<IActionResult> SaveDetail(SalesTaxRateDetail detail, SaveType saveType)
    {
        int resultId = 0;

        await db.Database.CreateExecutionStrategy().Execute(async () =>
        {
            using var dbContextTransaction = await db.Database.BeginTransactionAsync();
            SalesTaxRate? dbItem = null;
            if (saveType != SaveType.New)
            {
                dbItem = await (
                    from q in db.SalesTaxRates
                    where q.Id == detail.SalesTaxRateId
                    select q
                ).FirstOrDefaultAsync();
            }

            if (dbItem == null) //if the item does not exist then add it
            {
                dbItem = new SalesTaxRate();
                db.SalesTaxRates.Add(dbItem);
            }
            else
            {
                //remove existing items so that they get completely re-inserted
            }

            var d = detail;
            dbItem.Rate = d.Rate;
            dbItem.InactiveDate = d.InactiveDate;
            dbItem.CountyId = d.CountyId;

            await db.SaveChangesAsync();
            resultId = dbItem.Id;

            await dbContextTransaction.CommitAsync();
        });

        return Ok(resultId);
    }

    [Permission("Sales Tax Rate", PermissionType.Modify)]
    [Route("[action]/{id}")]
    public async Task<IActionResult> DeleteDetail(int id)
    {
        SalesTaxRate dbItem = await db.SalesTaxRates.Where(x => x.Id == id).FirstAsync();
        db.SalesTaxRates.Remove(dbItem);
        await db.SaveChangesAsync();

        return Ok();
    }
}



