using Fast.Web.Models;
namespace Fast.Web.Controllers;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class MeterTypeController : ODataController
{
    private readonly MyDbContext db;
    private readonly AuthorizationHelper authHelper;

    public MeterTypeController(MyDbContext context)
    {
        db = context;
        authHelper = new AuthorizationHelper(Main.IsAuthenticationEnabled);
    }

    [Permission("Meter Type", PermissionType.View)]
    [Route("/odata/GetMeterTypeItems")]
    public IActionResult GetItems(ODataQueryOptions<MeterTypeListItem> queryOptions, bool isExport)
    {
        queryOptions = Util.GetQueryOptionsWithConvertedDates(queryOptions);
        var itemsQueryable = GetItemsInternal();
        var items = (queryOptions.ApplyTo(itemsQueryable) as IEnumerable<MeterTypeListItem>)?.ToList();

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

    [Permission("Meter Type", PermissionType.View)]
    [Route("[action]")]
    public IQueryable<MeterTypeListItem> GetItemsInternal()
    {
        IQueryable<MeterTypeListItem>? itemsQueryable = null;

        itemsQueryable = (
            from q in db.MeterTypes
            select new MeterTypeListItem
            {
                MeterTypeId = q.Id,
                MeterType = q.Name
            }

        ).AsNoTracking();

        return itemsQueryable;
    }

    [Permission("Meter Type", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetRequiredData()
    {
        var hasModifyPermission = await authHelper.IsAuthorizedAsync(User, "Meter Type", PermissionType.Modify);

        var result = new { hasModifyPermission };
        return Ok(result);
    }

    [Permission("Meter Type", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetDetail(string MeterTypeName)
    {
        var detail = await (
            from q in db.MeterTypes
            where q.Name == MeterTypeName
            select new MeterTypeDetail
            {
                MeterTypeId = q.Id,
                MeterTypeName = q.Name,
            }
        ).AsNoTracking().FirstAsync();

        return Ok(detail);
    }

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

    [Permission("Meter Type", PermissionType.Modify)]
    [Route("[action]")]
    public async Task<IActionResult> SaveDetail(MeterTypeDetail detail, SaveType saveType)
    {
        int resultId = 0;
        await db.Database.CreateExecutionStrategy().Execute(async () =>
        {
            using var dbContextTransaction = await db.Database.BeginTransactionAsync();
            MeterType? dbItem = null;
            if (saveType != SaveType.New)
            {
                dbItem = await (
                    from q in db.MeterTypes
                    where q.Id == detail.MeterTypeId
                    select q
                ).FirstOrDefaultAsync();
            }

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

            var d = detail;
            dbItem.Name = d.MeterTypeName;

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

            await dbContextTransaction.CommitAsync();
        });

        return Ok(resultId);
    }

    [Permission("Meter Type", PermissionType.Modify)]
    [HttpDelete]
    [Route("[action]/{*Name}")]
    public async Task<IActionResult> DeleteMeterType(string Name)
    {
        MeterType dbitem = await db.MeterTypes.Where(x => x.Name == Name).FirstAsync();
        db.MeterTypes.Remove(dbitem);
        await db.SaveChangesAsync();

        return Ok();
    }
}
