using DynamicExpresso;
using Microsoft.AspNetCore.Components.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
using wispro.sp.entity;
using wispro.sp.share;
using wispro.sp.web.Auth;
using wispro.sp.web.Models;

namespace wispro.sp.web.Services
{
    public class AppealTypeService
    {
        private readonly IHttpService _httpClient;
        private readonly JwtAuthenticationStateProvider _jwt;
        private  List<AppealType> AppealTypes;

        public AppealTypeService(IHttpService httpClient, AuthenticationStateProvider jwt)
        {
            _httpClient = httpClient;
            _jwt = (JwtAuthenticationStateProvider)jwt;

            
        }

        public async Task<AppealRecord> getAppealRecord(int appealRecordId)
        {
            var data = await _httpClient.Get<AppealRecord>($"Appeal/GetAppealRecord?Id={appealRecordId}");
            return data;
        }

        public async Task<List<InputFieldValue>> GetInputFieldValues(int id, int state)
        {
            var data = await _httpClient.Get<List<InputFieldValue>>($"Appeal/GetInputFieldValues?Id={id}&state={state}");
            return data;
        }

        public async Task<List<AppealType>> GetItems()
        {
            if (AppealTypes == null)
            {
                AppealTypes = await _httpClient.Get<List<AppealType>>($"Appeal/GetAppealTypes");
                
            }
            return AppealTypes;
        }

        public List<AppealType> GetItems(int Type)
        {
            return AppealTypes.Where<AppealType>(at => at.Type == Type).ToList();
        }
        public List<AppealType> GetItems(PerformanceItem item)
        {
            List<AppealType> retList = new List<AppealType>();

            foreach (var at in GetItems(0))
            {
                if (!string.IsNullOrWhiteSpace(at.CanDoExpress))
                {
                    var interpreter = new Interpreter();
                    Func<PerformanceItem, bool> func = interpreter.ParseAsDelegate<Func<PerformanceItem, bool>>(at.CanDoExpress, "p");
                    bool result = func.Invoke(item);
                    
                    if (result)
                    {
                        retList.Add(at);
                    }
                }
                else
                {
                    retList.Add(at);
                }
            }

            return retList;
        }

        public async Task<List<AppealRecord>> GetUserAppeals(int? userid)
        {
            try {
                if (userid.HasValue)
                {
                    var data = await _httpClient.Get<List<AppealRecord>>($"Appeal/GetAppealRecords?userId={userid}");
                    Console.WriteLine();
                    return data;
                }
                else
                {
                    var data = await _httpClient.Get<List<AppealRecord>>($"Appeal/GetAppealRecords?userId=0");
                    return data;
                }
            }
            catch(Exception ex) {
                Console.WriteLine(ex);
                return new List<AppealRecord>();
            }

            
            
        }

        public async Task<List<AppealRecord>> GetUserAppeals(AppealRecordFilter filter)
        {
            var data = await _httpClient.Post<List<AppealRecord>>($"Appeal/QueryByFilter",filter);
            return data;
        }

        public async Task<AppealType> GetItem(int appealTypeId)
        {
            if (AppealTypes == null)
            {
                AppealTypes = await _httpClient.Get<List<AppealType>>($"Appeal/GetAppealTypes");
            }

            var retData = AppealTypes.Where<AppealType>(ap => ap.Id == appealTypeId).FirstOrDefault();

            return retData;
        }

        public async Task<List<InputField>> GetInputFields(int appealTypeId,int State)
        {
            var data = await _httpClient.Get<List<InputField>>($"Appeal/GetInputField?appealTypeId={appealTypeId}&state={State}");
            return data;
        }

        public async Task<List<AttachFile>> GetAppealRecordAttachFiles(int appealRecordId)
        {
            var data = await _httpClient.Get<List<AttachFile>>($"Appeal/GetAppealRecordAttachFiles?appealRecordId={appealRecordId}");
            return data;
        }

        public async Task CreateAppeal(CreateAppealModel model)
        {
            List<AttachFile> attachFiles = new List<AttachFile>();

            Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(model));

            foreach (var file in model.FileList)
            {
                AttachFile atfile = new AttachFile();
                var result = file.GetResponse<List<AttachFile>>();
                atfile.Id = result[0].Id;
                attachFiles.Add(atfile);
            }

            string strUrl = $"Appeal/CreateAppeal?ItemId={model.Item.Id}&typeid={model.AppealType.Id}&reviewerId={model.AppealRecord.ReviewerId}";
            AppealObject appealObject = new AppealObject();
            appealObject.attachFiles = attachFiles;
            appealObject.inputFieldValues = model.inputFieldValues;
            foreach(var fValue in appealObject.inputFieldValues)
            {
                fValue.InputField = null;
            }

            try
            {
                var data = await _httpClient.Post<ApiSaveResponse>(strUrl, appealObject);

                if (!data.Success)
                {
                    if (!data.Success)
                    {
                        throw new ApplicationException(data.ErrorMessage);
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                throw ex;
            }

        }

        public async Task<ApiSaveResponse> ReviewerAppeal(ReviewerAppealModel model)
        {

            string strUrl = $"Appeal/ReviewerAppeal?appealRecordId={model.AppealRecord.Id}";
            AppealObject appealObject = new AppealObject();
            appealObject.inputFieldValues = model.inputFieldValues;

            foreach (var fValue in appealObject.inputFieldValues)
            {
                fValue.InputField = null;
            }

            try
            {
                var data = await _httpClient.Post<ApiSaveResponse>(strUrl, appealObject);

                return data;
                
            }
            catch(Exception ex)
            {
                return new ApiSaveResponse()
                {
                    Success = false,
                    ErrorMessage = "审核发送未知错误！"

                };
                
            }

            //if (!data.IsSuccessStatusCode)
            //{
            //    string strContent = await data.Content.ReadAsStringAsync();
            //    throw new Exception(strContent);
            //}
        }

        public async Task<ApiSaveResponse> ChangeReviewer(AppealRecord changedRecord)
        {
            var data = await _httpClient.Get<ApiSaveResponse>($"Appeal/ChangeRecordReviewer?RecordId={changedRecord.Id}&ReviewerId={changedRecord.ReviewerId}");
            return data;
        }
    }
}
