using ZelWiki.Engine.Function;
using ZelWiki.Engine.Library;
using ZelWiki.Engine.Library.Interfaces;

namespace ZelWiki.Engine.Implementation
{
    /// <summary>
    /// 
    /// </summary>
    public class ProcessingInstructionFunctionHandler : IProcessingInstructionFunctionHandler
    {
        private static FunctionPrototypeCollection? _collection;

        public FunctionPrototypeCollection Prototypes
        {
            get
            {
                if (_collection == null)
                {
                    _collection = new FunctionPrototypeCollection(FunctionPrototypeCollection.WikiFunctionType.Instruction);

                    #region Prototypes.

                    //Processing instructions:
                    _collection.Add("@@Deprecate:");
                    _collection.Add("@@Protect:<bool>{isSilent}='false'");
                    _collection.Add("@@Tags: <string:infinite>[pageTags]");
                    _collection.Add("@@Template:");
                    _collection.Add("@@Review:");
                    _collection.Add("@@NoCache:");
                    _collection.Add("@@Include:");
                    _collection.Add("@@Draft:");
                    _collection.Add("@@HideFooterComments:");
                    _collection.Add("@@Title:<string>[pageTitle]");
                    _collection.Add("@@HideFooterLastModified:");

                    #endregion
                }

                return _collection;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="state"></param>
        /// <param name="function"></param>
        /// <param name="scopeBody"></param>
        /// <returns></returns>
        public HandlerResult Handle(IZelEngineState state, FunctionCall function, string? scopeBody = null)
        {
            switch (function.Name.ToLower())
            {
                case "tags": //##tag(pipe|separated|list|of|tags)
                    {
                        var tags = function.Parameters.GetList<string>("pageTags");
                        state.Tags.AddRange(tags);
                        state.Tags = state.Tags.Distinct().ToList();

                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "title":
                    {
                        state.PageTitle = function.Parameters.Get<string>("pageTitle");

                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "hidefooterlastmodified":
                    {
                        state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.HideFooterLastModified);

                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "hidefootercomments":
                    {
                        state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.HideFooterComments);
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "nocache":
                    {
                        state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.NoCache);
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "deprecate":
                    {
                        if (state.NestDepth == 0)
                        {
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Deprecate);
                            state.Headers.Add("<div class=\"alert alert-danger\">此页面已被弃用，最终将被删除.</div>");
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "protect":
                    {
                        if (state.NestDepth == 0)
                        {
                            bool isSilent = function.Parameters.Get<bool>("isSilent");
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Protect);
                            if (isSilent == false)
                            {
                                state.Headers.Add("<div class=\"alert alert-info\">此页面已受到保护，非版主无法更改.</div>");
                            }
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "template":
                    {
                        if (state.NestDepth == 0)
                        {
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Template);
                            state.Headers.Add("<div class=\"alert alert-secondary\">此页面是一个模板，不会出现在索引或术语表中.</div>");
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "review":
                    {
                        if (state.NestDepth == 0)
                        {
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Review);
                            state.Headers.Add("<div class=\"alert alert-warning\">此页面已被标记为待审核，其内容可能不准确.</div>");
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "include":
                    {
                        if (state.NestDepth == 0)
                        {
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Include);
                            state.Headers.Add("<div class=\"alert alert-secondary\">此页为包含页，不会出现在索引或术语表中.</div>");
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }

                //------------------------------------------------------------------------------------------------------------------------------
                case "draft":
                    {
                        if (state.NestDepth == 0)
                        {
                            state.ProcessingInstructions.Add(ZelWiki.Library.Constants.WikiInstruction.Draft);
                            state.Headers.Add("<div class=\"alert alert-warning\">本页为草稿，可能包含不正确的信息包括但不仅限于实验性样式.</div>");
                        }
                        return new HandlerResult(string.Empty)
                        {
                            Instructions = [Constants.HandlerResultInstruction.TruncateTrailingLine]
                        };
                    }
            }

            return new HandlerResult() { Instructions = [Constants.HandlerResultInstruction.Skip] };
        }
    }
}
