using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using InternshipSystem.Api.Commands;
using InternshipSystem.Api.Controllers;
using InternshipSystem.Api.Security;
using InternshipSystem.Api.UseCases;
using InternshipSystem.Core;
using InternshipSystem.Repository;
using Machine.Specifications;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace InternshipSystem.Api.Test
{
    [Subject(typeof(JsonSerializer))]
    class When_deserializing_cas
    {
        private static string json;
        
        
        private Establish context = () =>
        {
            // {
            //     "service": "https://system-praktyk.stg.kadet.net/user/login/code",
            //     "attributes": {
            //         "albumNumber": "165581",
            //         "firstName": "Kacper",
            //         "lastName": "Donat",
            //         "mail": [
            //         "kacdonat@pg.edu.pl",
            //         "kacper.donat@pg.edu.pl",
            //         "s165581@student.pg.edu.pl"
            //             ],
            //         "personNumber": "1101074",
            //         "PG_CUI_PORTALROLES": [
            //         "ROLE_EKONTAKT_PROD",
            //         "RP_STUDENT",
            //         "RP_USER",
            //         "ROLE_TRAC",
            //         "ROLE_HUDSON",
            //         "ROLE_WWW_ADMIN",
            //         "RP_PRACOWNIK"
            //             ]
            //     },
            //     "id": "1101074",
            //     "client_id": "PraktykiClientId"
            // }
            
            json =
                "    {\r\n        \"service\": \"https://system-praktyk.stg.kadet.net/user/login/code\",\r\n        \"attributes\": {\r\n            \"albumNumber\": \"165581\",\r\n            \"firstName\": \"Kacper\",\r\n            \"lastName\": \"Donat\",\r\n            \"mail\": [\r\n            \"kacdonat@pg.edu.pl\",\r\n            \"kacper.donat@pg.edu.pl\",\r\n            \"s165581@student.pg.edu.pl\"\r\n                ],\r\n            \"personNumber\": \"1101074\",\r\n            \"PG_CUI_PORTALROLES\": [\r\n            \"ROLE_EKONTAKT_PROD\",\r\n            \"RP_STUDENT\",\r\n            \"RP_USER\",\r\n            \"ROLE_TRAC\",\r\n            \"ROLE_HUDSON\",\r\n            \"ROLE_WWW_ADMIN\",\r\n            \"RP_PRACOWNIK\"\r\n                ]\r\n        },\r\n        \"id\": \"1101074\",\r\n        \"client_id\": \"PraktykiClientId\"\r\n    }";

            options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            };
        };

        private Because of = () => result = JsonSerializer.Deserialize<CasUserProfile>(json, options);

        private It should_nop = () => true.ShouldBeTrue();
        
        private static JsonSerializerOptions options;
        private static CasUserProfile result;
    }

    class When_doint_whatever
    {
        private Establish context = () =>
        {
            var db = new InternshipDbContext(new DbContextOptionsBuilder<InternshipDbContext>()
                .UseLoggerFactory(LoggerFactory.Create(b => b.AddConsole()))
                .UseNpgsql("Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=szwoniu")
                .Options);

            var company = Company.CreateCompany("a", "b");

            var internship = db.Editions.First();

            var list = new List<UpdateRegistrationForm> {null}.Select(form => form.Company).ToList();

            db.Companies.Add(company);

            db.SaveChanges();
        };

        private It should_whatev = () => true.ShouldBeTrue();
    }
    
    class When_writing_tests_only_for_debug_because_i_gave_up_on_code_quality
    {
        private Establish context = () =>
        {
            var db = new InternshipDbContext(new DbContextOptionsBuilder<InternshipDbContext>()
                .UseLoggerFactory(LoggerFactory.Create(b => b.AddConsole()))
                .UseNpgsql("Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=szwoniu")
                .Options);

            var ed = db.Editions
                .Include(e => e.AvailableInternshipTypes)
                .ThenInclude(t => t.InternshipType)
                .Include(e => e.AvailableSubjects)
                .ThenInclude(t => t.Subject)
                .First();

            var user = new User
            {
                PersonNumber = 1
            };
            
            var ir =  db.Entry(ed)
                .Collection(e => e.Internships)
                .Query()
                .Include(i => i.InternshipRegistration)
                    .ThenInclude(r => r.BranchAddress)
                .Include(i => i.InternshipRegistration)
                    .ThenInclude(r => r.Company)
                .Include(i => i.InternshipRegistration)
                    .ThenInclude(c => c.Company.Branches)
                .Include(i => i.InternshipRegistration)
                    .ThenInclude(c => c.Type)
                .Include(i => i.InternshipRegistration)
                    .ThenInclude(c => c.Subjects)
                .Where(i => i.Student.Id == user.PersonNumber)
                .Select(i => i.InternshipRegistration)
                .First();

            var useCase = new UpdateInternshipRegistrationUseCase(db, ir, ed, user);

            var update = new UpdateRegistrationForm
            {
                Subjects = new List<long>
                {
                  1,
                  2,
                  3
                },
                Type = 1
            };

            var task = useCase.UpdateInternshipRegistration(update, CancellationToken.None);

            task.Wait();

            var result = task.Result;

            db.SaveChanges();

            ir = db.Entry(ed)
                .Collection(e => e.Internships)
                .Query()
                .Include(i => i.InternshipRegistration)
                .ThenInclude(r => r.BranchAddress)
                .Include(i => i.InternshipRegistration)
                .ThenInclude(r => r.Company)
                .Include(i => i.InternshipRegistration)
                .ThenInclude(c => c.Company.Branches)
                .Include(i => i.InternshipRegistration)
                .ThenInclude(c => c.Type)
                .Include(i => i.InternshipRegistration)
                .ThenInclude(c => c.Subjects)
                .Where(i => i.Student.Id == user.PersonNumber)
                .Select(i => i.InternshipRegistration)
                .First();
        };
        
        private It should_nop = () => true.ShouldBeTrue();
    }
}