text: ﻿using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Threading.Tasks;
  using ClassifiedAds.IdentityServer.Models.IdentityResourceModels;
  using IdentityServer4.EntityFramework.DbContexts;
  using IdentityServer4.EntityFramework.Entities;
  using Microsoft.AspNetCore.Mvc;
  using Microsoft.EntityFrameworkCore;
  using Newtonsoft.Json;
  
  namespace ClassifiedAds.IdentityServer.Controllers
  {
      public class IdentityResourceController : Controller
      {
          private readonly ConfigurationDbContext _configurationDbContext;
  
          public IdentityResourceController(ConfigurationDbContext configurationDbContext)
          {
              _configurationDbContext = configurationDbContext;
          }
  
          public IActionResult Index()
          {
              var itentities = _configurationDbContext.IdentityResources.ToList();
              return View(itentities.ToModels().ToList());
          }
  
          public IActionResult Add()
          {
              return View(nameof(Edit), new IdentityResourceModel());
          }
  
          public IActionResult Edit(int id)
          {
              var identity = _configurationDbContext.IdentityResources
                  .Include(x => x.UserClaims)
                  .FirstOrDefault(x => x.Id == id);
              return View(identity.ToModel());
          }
  
          [HttpPost]
          public IActionResult Edit(IdentityResourceModel model)
          {
              IdentityResource identity;
              if (model.Id == 0)
              {
                  identity = new IdentityResource
                  {
                      UserClaims = new List<IdentityClaim>(),
                  };
                  _configurationDbContext.IdentityResources.Add(identity);
              }
              else
              {
                  identity = _configurationDbContext.IdentityResources
                      .Include(x => x.UserClaims)
                      .FirstOrDefault(x => x.Id == model.Id);
                  identity.UserClaims.Clear();
              }
  
              model.UpdateEntity(identity);
  
              if (!string.IsNullOrEmpty(model.UserClaimsItems))
              {
                  model.UserClaims = JsonConvert.DeserializeObject<List<string>>(model.UserClaimsItems);
  
                  identity.UserClaims.AddRange(model.UserClaims.Select(x => new IdentityClaim
                  {
                      Type = x,
                  }));
              }
  
              _configurationDbContext.SaveChanges();
  
              return RedirectToAction(nameof(Edit), new { id = identity.Id });
          }
  
          public IActionResult Delete(int id)
          {
              var identity = _configurationDbContext.IdentityResources
                  .Include(x => x.UserClaims)
                  .FirstOrDefault(x => x.Id == id);
              return View(identity.ToModel());
          }
  
          [HttpPost]
          public IActionResult Delete(IdentityResourceModel model)
          {
              var identity = _configurationDbContext.IdentityResources
                  .FirstOrDefault(x => x.Id == model.Id);
  
              _configurationDbContext.IdentityResources.Remove(identity);
              _configurationDbContext.SaveChanges();
  
              return RedirectToAction(nameof(Index));
          }
  
          public IActionResult Properties(int id)
          {
              var identity = _configurationDbContext.IdentityResources
                  .Include(x => x.Properties)
                  .FirstOrDefault(x => x.Id == id);
              return View(PropertiesModel.FromEntity(identity));
          }
  
          [HttpPost]
          public IActionResult AddProperty(PropertiesModel model)
          {
              var identity = _configurationDbContext.IdentityResources
                  .Include(x => x.Properties)
                  .FirstOrDefault(x => x.Id == model.IdentityResourceId);
  
              identity.Properties.Add(new IdentityResourceProperty
              {
                  Key = model.Key,
                  Value = model.Value,
              });
  
              _configurationDbContext.SaveChanges();
  
              return RedirectToAction(nameof(Properties), new { id = identity.Id });
          }
  
          [HttpGet]
          public IActionResult DeleteProperty(int id)
          {
              var prop = _configurationDbContext.Set<IdentityResourceProperty>()
                  .Include(x => x.IdentityResource)
                  .FirstOrDefault(x => x.Id == id);
              return View(IdentityResourcePropertyModel.FromEntity(prop));
          }
  
          [HttpPost]
          public IActionResult DeleteProperty(IdentityResourcePropertyModel model)
          {
              var identity = _configurationDbContext.IdentityResources
                              .Include(x => x.Properties)
                              .FirstOrDefault(x => x.Id == model.IdentityResource.Id);
              var prop = identity.Properties.FirstOrDefault(x => x.Id == model.Id);
              identity.Properties.Remove(prop);
              _configurationDbContext.SaveChanges();
  
              return RedirectToAction(nameof(Properties), new { id = identity.Id });
          }
  
          public IActionResult GetClaims()
          {
              // http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
              var standardClaims = new List<string>
              {
                  "name",
                  "given_name",
                  "family_name",
                  "middle_name",
                  "nickname",
                  "preferred_username",
                  "profile",
                  "picture",
                  "website",
                  "gender",
                  "birthdate",
                  "zoneinfo",
                  "locale",
                  "address",
                  "updated_at",
              };
  
              return Ok(standardClaims);
          }
      }
  }