using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using StockFin.Models;
using StockFin.ViewModels;

namespace StockFin.Controllers
{
    public class StatementsController : Controller
    {
        private readonly FinancesContext _context=new FinancesContext();

        //public StatementsController(FinancesContext context)
        //{
        //    _context = context;
        //}

        // GET: Statements
        public async Task<IActionResult> Index()
        {
            var statements = await _context.Statements
                .Include(s => s.Account)
                .OrderByDescending(s => s.Date)
                .ToListAsync();

            return View(statements);
        }

        // GET: Statements/Create
        public async Task<IActionResult> Create()
        {
            await PopulateAccountsDropDownAsync();
            return View();
        }

        // POST: Statements/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Id,Date,AccountId,Value")] Statement statement)
        {
            if (ModelState.IsValid)
            {
                _context.Add(statement);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }

            await PopulateAccountsDropDownAsync(statement.AccountId);
            return View(statement);
        }

        // GET: Statements/Edit/5
        public async Task<IActionResult> Edit(long? id)
        {
            if (id == null) return NotFound();

            var statement = await _context.Statements.FindAsync(id.Value);
            if (statement == null) return NotFound();

            await PopulateAccountsDropDownAsync(statement.AccountId);
            return View(statement);
        }

        // POST: Statements/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(long id, [Bind("Id,Date,AccountId,Value")] Statement statement)
        {
            if (id != statement.Id) return NotFound();

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(statement);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!StatementExists(statement.Id)) return NotFound();
                    else throw;
                }

                return RedirectToAction(nameof(Index));
            }

            await PopulateAccountsDropDownAsync(statement.AccountId);
            return View(statement);
        }

        // GET: Statements/Delete/5
        public async Task<IActionResult> Delete(long? id)
        {
            if (id == null) return NotFound();

            var statement = await _context.Statements
                .Include(s => s.Account)
                .FirstOrDefaultAsync(s => s.Id == id.Value);

            if (statement == null) return NotFound();

            return View(statement);
        }

        // POST: Statements/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(long id)
        {
            var statement = await _context.Statements.FindAsync(id);
            if (statement != null)
            {
                _context.Statements.Remove(statement);
                await _context.SaveChangesAsync();
            }

            return RedirectToAction(nameof(Index));
        }

        private bool StatementExists(long id)
        {
            return _context.Statements.Any(e => e.Id == id);
        }

        private async Task PopulateAccountsDropDownAsync(long? selectedAccountId = null)
        {
            var accounts = await _context.Accounts.OrderBy(a => a.Title).Select(a => new
            {
                a.Id,
                DisplayTitle = a.Bank + " - " + a.Title
            }).ToListAsync();
            ViewData["AccountId"] = new SelectList(accounts, "Id", "DisplayTitle", selectedAccountId);
        }

        // GET: Statements/CreateToday
        public async Task<IActionResult> CreateToday()
        {
            var accounts = await _context.Accounts.Where(t=>t.TypeId==1 || t.TypeId == 2 || t.TypeId == 4)
                .Include(a => a.Type)
                .OrderBy(a => a.Title)
                .ToListAsync();

            var vm = new CreateTodayViewModel
            {
                Date = DateTime.Today,
                Accounts = accounts.Select(a => new CreateTodayViewModel.AccountEntry
                {
                    Bank = a.Bank,
                    AccountId       = a.Id,
                    AccountName     = a.Title,
                    AccountTypeName = a.Type?.Title,
                }).ToList()
            };

            return View(vm);
        }

        // POST: Statements/CreateToday
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> CreateToday(CreateTodayViewModel vm)
        {
            if (!ModelState.IsValid)
                return View(vm);

            var statements = vm.Accounts
                .Where(a => a.Amount.HasValue)
                .Select(a => new Statement
                {
                    Date      = vm.Date,
                    AccountId = a.AccountId,
                    Value    = a.Amount!.Value,
                });

            _context.Statements.AddRange(statements);
            await _context.SaveChangesAsync();

            return RedirectToAction(nameof(Index));
        }
    }
}
