namespace Fast.Web.Controllers;

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

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

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

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

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

        itemsQueryable = (
            from q in db.Plants
            select new PlantListItem
            {
                PlantId = q.Id,
                PlantName = q.Name,
                IsActive = q.IsActive ? "yes" : "no"

            }
        ).AsNoTracking();

        return itemsQueryable;
    }

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

    [Permission("Plant", PermissionType.View)]
    [Route("[action]")]
    public async Task<IActionResult> GetDetail(int id)
    {
        var detail = await (
            from q in db.Plants
            where q.Id == id
            select new PlantDetail
            {
                PlantId = q.Id,
                PlantName = q.Name,
                IsActive = q.IsActive
            }
        ).AsNoTracking().FirstAsync();

        return Ok(detail);
    }

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

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

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

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

            var d = detail;
            dbItem.Name = d.PlantName;
            dbItem.IsActive = d.IsActive;

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

            await dbContextTransaction.CommitAsync();
        });

        return Ok(resultId);
    }

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

        return Ok();
    }
}

