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

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

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

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

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

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

        itemsQueryable = (
            from q in db.PayoutTypes
            select new PayoutTypeListItem
            {
                PayoutTypeId = q.Id,
                PayoutType = q.Name,
                Description = q.Description
            }

        ).AsNoTracking();

        return itemsQueryable;
    }

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

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

    [Permission("Payout Type", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetDetail(string PayoutTypeName)
    {
        var detail = await (
            from q in db.PayoutTypes
            where q.Name == PayoutTypeName
            select new PayoutTypeDetail
            {
                PayoutTypeId = q.Id,
                PayoutTypeName = q.Name,
                Description = q.Description
            }
        ).AsNoTracking().FirstAsync();

        return Ok(detail);
    }

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

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

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

            var d = detail;
            dbItem.Name = d.PayoutTypeName;
            dbItem.Description = d.Description;

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

            await dbContextTransaction.CommitAsync();
        });

        return Ok(resultId);
    }

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

        return Ok();
    }
}
