using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

using FMSAdmin.Data;
using FMSAdmin.Helpers;
using FMSAdmin.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using FMSAdmin.Models;

namespace FMSApp.Services {
    public class MobileShortcutService {
        private readonly ILogger<MobileShortcutService> _logger;
        private readonly FMSContext _context;

        private readonly AppSettings _appSettings;

        public MobileShortcutService(
            ILogger<MobileShortcutService> logger,
            FMSContext context,
            IOptions<AppSettings> appSettings) {
            _logger = logger;
            _context = context;
            _appSettings = appSettings.Value;
        }

        public void CopyFromDefault(string userId, ShortcutType type) {
            var userShortcutCount = _context.MobileShortcut.Where(
                x => x.UserId == userId
                && x.Type == type
            ).Count();
            if (userShortcutCount == 0) {
                var defaultShortcuts = _context.MobileShortcut.Where(
                    x => (x.UserId == null || x.UserId == "")
                    && x.Type == type
                ).OrderBy(x => x.Position).ToList();

                int position = 0;
                foreach (var def in defaultShortcuts) {
                    position++;

                    var shortcut = new MobileShortcut();
                    shortcut.UserId = userId;
                    shortcut.SitemapId = def.SitemapId;
                    shortcut.Type = def.Type;
                    shortcut.Icon = def.Icon;
                    shortcut.MobileShortcutId = 0;
                    shortcut.Position = position;
                    shortcut.Created = DateTime.Now;
                    shortcut.Updated = DateTime.Now;
                    _context.MobileShortcut.Add(shortcut);
                }
                _context.SaveChanges();
            }
        }

        public void RePosition(string userId, ShortcutType type) {
            var list = _context.MobileShortcut.Where(
                x => x.UserId == userId
                && x.Type == type
                && x.IsDelete == false
            );
            int position = 0;
            foreach (var item in list) {
                position++;

                item.Position = position;
                _context.MobileShortcut.Update(item);
            }
            _context.SaveChanges();
        }

        public void PositionUp(string userId, int sitemapId, ShortcutType type) {
            CopyFromDefault(userId, type);

            var me = _context.MobileShortcut.FirstOrDefault(
                x => x.UserId == userId
                && x.SitemapId == sitemapId
                && x.Type == type
                && x.IsDelete == false
            );
            if (me == null) return;

            var prev = _context.MobileShortcut.Where(
                x => x.UserId == userId
                && x.Type == type
                && x.Position < me.Position
                && x.IsDelete == false
            ).OrderByDescending(x => x.Position).FirstOrDefault();
            if (prev == null) return;

            var myPosition = me.Position;
            me.Position = prev.Position;
            prev.Position = myPosition;

            _context.MobileShortcut.Update(me);
            _context.MobileShortcut.Update(prev);
            _context.SaveChanges();
        }

        public void PositionDown(string userId, int sitemapId, ShortcutType type) {
            CopyFromDefault(userId, type);

            var me = _context.MobileShortcut.FirstOrDefault(
                x => x.UserId == userId
                && x.SitemapId == sitemapId
                && x.Type == type
                && x.IsDelete == false
            );
            if (me == null) return;

            var next = _context.MobileShortcut.Where(
                x => x.UserId == userId
                && x.Type == type
                && x.Position > me.Position
                && x.IsDelete == false
            ).OrderBy(x => x.Position).FirstOrDefault();
            if (next == null) return;

            var myPosition = me.Position;
            me.Position = next.Position;
            next.Position = myPosition;

            _context.MobileShortcut.Update(me);
            _context.MobileShortcut.Update(next);
            _context.SaveChanges();
        }

        public void Save(MobileShortcut data) {
            CopyFromDefault(data.UserId, data.Type);

            var persist = _context.MobileShortcut.Where(
                x => x.UserId == data.UserId
                && x.SitemapId == data.SitemapId
                && x.Type == data.Type
                && x.IsDelete == false
            ).FirstOrDefault();

            // 등록시 중복체크
            if (data.MobileShortcutId == 0 && persist != null) {
                throw new ServiceException("이미 등록되어있는 메뉴입니다.");
            }

            if (data.MobileShortcutId != 0 && persist == null) {
                // 기존 데이터 수정
                persist = _context.MobileShortcut.FirstOrDefault(
                    x => x.MobileShortcutId == data.MobileShortcutId
                );
                if (persist != null) {
                    persist.SitemapId = data.SitemapId;
                    persist.Icon = data.Icon;
                    persist.Updated = DateTime.Now;
                }
            } else if (persist == null) {
                var maxPosition = _context.MobileShortcut.Where(
                    x => x.UserId == data.UserId
                    && x.Type == data.Type
                    && x.IsDelete == false
                ).Max(x => x.Position);

                data.Created = DateTime.Now;
                data.Updated = DateTime.Now;
                data.Position = maxPosition + 1;

                _context.MobileShortcut.Add(data);
                _context.SaveChanges();
            } else {
                persist.SitemapId = data.SitemapId;
                persist.Icon = data.Icon;
                persist.Updated = DateTime.Now;

                _context.MobileShortcut.Update(persist);
                _context.SaveChanges();
            }

            RePosition(data.UserId, data.Type);
        }

        public IQueryable<MobileShortcut> GetAll() {
            var query = _context.MobileShortcut;
            return query;
        }

        public void Delete(string userId, int sitemapId, ShortcutType type) {
            CopyFromDefault(userId, type);

            var item = _context.MobileShortcut.FirstOrDefault(
                x => x.UserId == userId
                && x.SitemapId == sitemapId
                && x.Type == type
                && x.IsDelete == false
            );

            if (item != null) {
                _context.MobileShortcut.Remove(item);
                _context.SaveChanges();
            }

            RePosition(userId, type);
        }
    }
}