
using Moq;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using User.Insight.Tracker.Controllers;
using User.Insight.Tracker.Services;
using User.Insight.Tracker.DataContracts;
using User.Insight.Tracker.DataContracts.Requests;
using User.Insight.Tracker.DataContracts.Response;
using User.Insight.Tracker.Common;
using System.Net;


namespace Insight.Tracker.UnitTest
{
    public class CommonControllerTests
    {
        private readonly Mock<ILogger<CommonController>> _loggerMock;
        private readonly Mock<ICommonService> _serviceMock;
        private readonly CommonController _controller;

        public CommonControllerTests()
        {
            _loggerMock = new Mock<ILogger<CommonController>>();
            _serviceMock = new Mock<ICommonService>();
           
            var contextAccessor = SetHttpContext();
            _controller = new CommonController(
                _loggerMock.Object,
                _serviceMock.Object,
                contextAccessor.Object
            );
          
        }
        private Mock<IHttpContextAccessor> SetHttpContext()
        {
            var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
            var context = new DefaultHttpContext();
            mockHttpContextAccessor.Setup(_ => _.HttpContext).Returns(context);
            return mockHttpContextAccessor;
        }

        [Fact]
        public void GetAudit_ReturnsOk_WithExpectedPayload()
        {
            // Arrange
            var searchRequest = new SearchRequest<AuditRequest>
            {
                SearchText = "test",
                PageNumber = 1,
                PageSize = 10,
                Filter = new AuditRequest { StartDate = DateTime.UtcNow.AddDays(-1), EndDate = DateTime.UtcNow }
            };

            var expectedData = new PageResponse<AuditResponse>
            {
                Records = new List<AuditResponse>
            {
                new AuditResponse
                {
                    Id = 1,
                    table_name = "TestTable",
                    operation_type = "INSERT",
                    old_data = "{}",
                    new_data = "{\"Id\":1}",
                    changed_by = "admin",
                    updated_on = DateTime.UtcNow,
                    UserName = "admin"
                }
            },
                TotalRecords = 1,
                TotalPages = 1,
                PageSize = 10,
                CurrentPage = 1
            };

            _serviceMock
                .Setup(s => s.GetAudit(searchRequest, It.IsAny<JwtTokenDetail>()))
                .Returns(expectedData);

            // Act
            var result = _controller.GetAudit(searchRequest);

            // Assert
            var objectResult = Assert.IsType<ObjectResult>(result.Result);
            Assert.Equal((int)HttpStatusCode.OK, objectResult.StatusCode);

            var payload = Assert.IsType<Payload<PageResponse<AuditResponse>>>(objectResult.Value);
            Assert.True(payload.IsSuccess);
            Assert.Equal(Constant.MsgSuccess, payload.Message);
            Assert.Equal(expectedData, payload.Data);
        }

        [Fact]
        public void GetAudit_ReturnsOk_WithNullData()
        {
            // Arrange
            var searchRequest = new SearchRequest<AuditRequest>();
            _serviceMock
                .Setup(s => s.GetAudit(searchRequest, It.IsAny<JwtTokenDetail>()))
                .Returns((PageResponse<AuditResponse>)null);

            // Act
            var result = _controller.GetAudit(searchRequest);

            // Assert
            var objectResult = Assert.IsType<ObjectResult>(result.Result);
            Assert.Equal((int)HttpStatusCode.OK, objectResult.StatusCode);

            var payload = Assert.IsType<Payload<PageResponse<AuditResponse>>>(objectResult.Value);
            Assert.True(payload.IsSuccess);
            Assert.Equal(Constant.MsgSuccess, payload.Message);
            Assert.Null(payload.Data);
        }

        [Fact]
        public void GetAudit_ThrowsException_ReturnsException()
        {
            // Arrange
            var searchRequest = new SearchRequest<AuditRequest>();
            _serviceMock
                .Setup(s => s.GetAudit(searchRequest, It.IsAny<JwtTokenDetail>()))
                .Throws(new Exception("Service error"));

            // Act & Assert
            Assert.Throws<Exception>(() => _controller.GetAudit(searchRequest));
        }
    }

}
