#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Twilio.AspNet.Common;
using TwilioSMSReceiver;
using TwilioSMSReceiver.Data;
using TwilioSMSReceiver.Data.Models;
using TwilioSMSReceiver.Common.Interfaces;
using TwilioSMSReceiver.Common.Handlers;

namespace TwilioSMSReceiver.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SMSReceiverController : ControllerBase
    {
        private readonly SMSDbCtx _context;
        private readonly IEnumerable<IMessageHandler> _messageHandlers;
        private readonly IWebHostEnvironment _environment;

        public SMSReceiverController(SMSDbCtx context, IEnumerable<IMessageHandler> messageHandlers,
            IWebHostEnvironment environment)
        {
            _context = context;
            _messageHandlers = messageHandlers;
            _environment = environment;
        }

        // GET: api/SMSReceiver
        [HttpGet]
        public async Task<ActionResult<IEnumerable<SMSModel>>> GetSMSMessages()
        {
            if (_environment.IsDevelopment())
            {
                return await _context.SMSMessages.Include(b => b.MMSContent).ToListAsync();
            }
            return NotFound();
        }

        // GET: api/SMSReceiver/5
        [HttpGet("{id}")]
        public async Task<ActionResult<SMSModel>> GetSMSModel(int id)
        {
            var sMSModel = await _context.SMSMessages.FindAsync(id);

            if (sMSModel == null)
            {
                return NotFound();
            }

            return sMSModel;
        }
        // POST: api/SMSReceiver
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<SMSModel>> PostSMSModel([FromForm]SmsRequest smsRequest, [FromForm] int? numMedia)
        {
            SMSModel message = ProcessTwilioSMS(smsRequest, numMedia);

            _context.SMSMessages.Add(message);
            await _context.SaveChangesAsync();

            List<Task> _HandleAllMessages = new List<Task>();

            foreach (var handler in _messageHandlers)
            {
                _HandleAllMessages.Add(handler.RelaySms(message));
            }
            return Ok();
        }

        [NonAction]
        protected SMSModel ProcessTwilioSMS(SmsRequest smsRequest, int? numMedia)
        {
            var mmsItems = new List<MMSModel>();
            var message = new SMSModel
            {
                MessageContents = smsRequest.Body,
                SenderNumber = smsRequest.From,
                ReceivedNumber = smsRequest.To,
                TimeReceived = DateTime.UtcNow
            };

            if (numMedia != null)
            {
                for (var i = 0; i < numMedia; i++)
                {
                    var uri = Request.Form[$"MediaUrl{i}"];

                    mmsItems.Add(new MMSModel { OriginalMMSData = uri });
                }

                message.MMSContent = mmsItems;
            }

            return message;
        }

        private bool SMSModelExists(int id)
        {
            return _context.SMSMessages.Any(e => e.Id == id);
        }
    }
}
