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

namespace Fast.Web.Controllers;

[Authorize]
[ApiController]
[Route("api/[controller]")]

public class SeveranceTaxController(MyDbContext context) : ODataController
{
    private readonly MyDbContext db = context;
    private readonly AuthorizationHelper authHelper = new(Main.IsAuthenticationEnabled);

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

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

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

        itemsQueryable = (
            from q in db.VwSeveranceTaxOverviewInfos
            select new SeveranceTaxListItem
            {
                StateId = q.StateId,
                StateName = q.StateName,
                GasRate = q.GasRate,
                GasRegulatoryFee = q.GasRegFee,
                CrudeRate = q.CrudeRate,
                CrudeRegulatoryFee = q.CrudeRegFee,
            }
        ).AsNoTracking();
        return itemsQueryable;
    }


    [Permission("Severance Tax", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetRequiredData()
    {
        var hasModifyPermission = await authHelper.IsAuthorizedAsync(User, "Severance Tax", PermissionType.Modify);
        var states = await DataHelper.GetTerritoriesAsync();
        var result = new { hasModifyPermission, states };
        return Ok(result);
    }

    [Permission("Severance Tax", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetDetail(int stateId)
    {
        var gasData = await (from q in db.SeveranceTaxes where q.StateId == stateId && q.LeaseType.Id == 1 select q).FirstOrDefaultAsync();
        var crudeData = await (from q in db.SeveranceTaxes where q.StateId == stateId && q.LeaseType.Id == 2 select q).FirstOrDefaultAsync();
        var detail = new SeveranceTaxDetail();
        detail.StateId = stateId;
        detail.GasRate = gasData?.Rate;
        detail.GasRegulatoryFee = gasData?.RegulatoryFee;
        detail.CrudeRate = crudeData?.Rate;
        detail.CrudeRegulatoryFee = crudeData?.RegulatoryFee;
        return Ok(detail);
    }

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

    [Permission("Severance Tax", PermissionType.Modify)]
    [Route("[action]")]
    public async Task<IActionResult> SaveDetail(SeveranceTaxDetail d, SaveType saveType, int? originalStateId)
    {
        int resultId = 0;
        await db.Database.CreateExecutionStrategy().Execute(async () =>
        {
            using var dbContextTransaction = await db.Database.BeginTransactionAsync();
            if (saveType == SaveType.New)
            {
                await db.SeveranceTaxes
                    .Where(q => q.StateId == d.StateId)
                    .ForEachAsync(x => db.SeveranceTaxes.Remove(x));
                await db.SaveChangesAsync();
            }
            else //not new
            {
                await db.SeveranceTaxes
                    .Where(q => q.StateId == originalStateId)
                    .ForEachAsync(x => db.SeveranceTaxes.Remove(x));
                await db.SaveChangesAsync();
            }

            if (d.GasRate != null || d.GasRegulatoryFee != null)
            {
                var gasItem = new SeveranceTax();
                gasItem.LeaseTypeId = 1;
                gasItem.RegulatoryFee = d.GasRegulatoryFee;
                gasItem.Rate = d.GasRate ?? 0;
                gasItem.StateId = d.StateId;
                db.SeveranceTaxes.Add(gasItem);
            }

            if (d.CrudeRate != null || d.CrudeRegulatoryFee != null)
            {
                var crudeItem = new SeveranceTax();
                crudeItem.LeaseTypeId = 2;
                crudeItem.RegulatoryFee = d.CrudeRegulatoryFee;
                crudeItem.Rate = d.CrudeRate ?? 0;
                crudeItem.StateId = d.StateId;
                db.SeveranceTaxes.Add(crudeItem);
            }

            await db.SaveChangesAsync();
            await dbContextTransaction.CommitAsync();
        });

        return Ok(resultId);
    }

    [Permission("Severance Tax", PermissionType.Modify)]
    [Route("[action]/{stateId}")]
    public async Task<IActionResult> DeleteDetail(int stateId)
    {
        foreach (var item in db.SeveranceTaxes.Where(x => x.StateId == stateId))
        {
            db.SeveranceTaxes.Remove(item);
        }
        await db.SaveChangesAsync();
        return Ok();
    }
}
