using System;
using System.Text.Json.Serialization;

namespace Adaptation.FileHandlers.json.WorkItems;

internal class WorkItem
{

#nullable enable

    [JsonConstructor]
    public WorkItem(DateTime? activatedDate,
                    string areaPath,
                    string? assignedTo,
                    long? businessValue,
                    DateTime changedDate,
                    DateTime? closedDate,
                    int commentCount,
                    DateTime createdDate,
                    string description,
                    long? effort,
                    int id,
                    string iterationPath,
                    int? parent,
                    int? priority,
                    Relation[]? relations,
                    string? requester,
                    DateTime? resolvedDate,
                    int revision,
                    long? riskReductionMinusOpportunityEnablement,
                    DateTime? startDate,
                    string state,
                    string tags,
                    DateTime? targetDate,
                    long? timeCriticality,
                    string title,
                    string? violation,
                    long? weightedShortestJobFirst,
                    string workItemType)
    {
        ActivatedDate = activatedDate;
        AreaPath = areaPath;
        AssignedTo = assignedTo;
        BusinessValue = businessValue;
        ChangedDate = changedDate;
        ClosedDate = closedDate;
        CommentCount = commentCount;
        CreatedDate = createdDate;
        Description = description;
        Effort = effort;
        Id = id;
        IterationPath = iterationPath;
        Parent = parent;
        Priority = priority;
        Relations = relations;
        Requester = requester;
        ResolvedDate = resolvedDate;
        Revision = revision;
        RiskReductionMinusOpportunityEnablement = riskReductionMinusOpportunityEnablement;
        StartDate = startDate;
        State = state;
        Tags = tags;
        TargetDate = targetDate;
        TimeCriticality = timeCriticality;
        Title = title;
        Violation = violation;
        WeightedShortestJobFirst = weightedShortestJobFirst;
        WorkItemType = workItemType;
    }

    public override string ToString() => $"{Id} - {WorkItemType} - {Title}";

    public static WorkItem Get(WorkItem workItem, Relation[] relations)
    {
        WorkItem result = new(workItem.ActivatedDate,
                              workItem.AreaPath,
                              workItem.AssignedTo,
                              workItem.BusinessValue,
                              workItem.ChangedDate,
                              workItem.ClosedDate,
                              workItem.CommentCount,
                              workItem.CreatedDate,
                              workItem.Description,
                              workItem.Effort,
                              workItem.Id,
                              workItem.IterationPath,
                              workItem.Parent,
                              workItem.Priority,
                              relations,
                              workItem.Requester,
                              workItem.ResolvedDate,
                              workItem.Revision,
                              workItem.RiskReductionMinusOpportunityEnablement,
                              workItem.StartDate,
                              workItem.State,
                              workItem.Tags,
                              workItem.TargetDate,
                              workItem.TimeCriticality,
                              workItem.Title,
                              workItem.Violation,
                              workItem.WeightedShortestJobFirst,
                              workItem.WorkItemType);
        return result;
    }

    public static WorkItem? GetWithOutRelations(WorkItem? workItem)
    {
        WorkItem? result = workItem is null ? null : new(workItem.ActivatedDate,
                                                         workItem.AreaPath,
                                                         workItem.AssignedTo,
                                                         workItem.BusinessValue,
                                                         workItem.ChangedDate,
                                                         workItem.ClosedDate,
                                                         workItem.CommentCount,
                                                         workItem.CreatedDate,
                                                         workItem.Description,
                                                         workItem.Effort,
                                                         workItem.Id,
                                                         workItem.IterationPath,
                                                         workItem.Parent,
                                                         workItem.Priority,
                                                         Array.Empty<Relation>(),
                                                         workItem.Requester,
                                                         workItem.ResolvedDate,
                                                         workItem.Revision,
                                                         workItem.RiskReductionMinusOpportunityEnablement,
                                                         workItem.StartDate,
                                                         workItem.State,
                                                         workItem.Tags,
                                                         workItem.TargetDate,
                                                         workItem.TimeCriticality,
                                                         workItem.Title,
                                                         workItem.Violation,
                                                         workItem.WeightedShortestJobFirst,
                                                         workItem.WorkItemType);
        return result;
    }

    [JsonPropertyName("ActivatedDate")] public DateTime? ActivatedDate { get; }
    [JsonPropertyName("AreaPath")] public string AreaPath { get; }
    [JsonPropertyName("AssignedTo")] public string? AssignedTo { get; }
    [JsonPropertyName("BusinessValue")] public long? BusinessValue { get; }
    [JsonPropertyName("ChangedDate")] public DateTime ChangedDate { get; }
    [JsonPropertyName("ClosedDate")] public DateTime? ClosedDate { get; }
    [JsonPropertyName("CommentCount")] public int CommentCount { get; }
    [JsonPropertyName("CreatedDate")] public DateTime CreatedDate { get; }
    [JsonPropertyName("Description")] public string Description { get; }
    [JsonPropertyName("Effort")] public long? Effort { get; }
    [JsonPropertyName("Id")] public int Id { get; }
    [JsonPropertyName("IterationPath")] public string IterationPath { get; }
    [JsonPropertyName("Parent")] public int? Parent { get; }
    [JsonPropertyName("Priority")] public int? Priority { get; }
    [JsonPropertyName("Relations")] public Relation[]? Relations { get; }
    [JsonPropertyName("Requester")] public string? Requester { get; }
    [JsonPropertyName("ResolvedDate")] public DateTime? ResolvedDate { get; }
    [JsonPropertyName("Revision")] public int Revision { get; }
    [JsonPropertyName("RiskReductionMinusOpportunityEnablement")] public long? RiskReductionMinusOpportunityEnablement { get; }
    [JsonPropertyName("StartDate")] public DateTime? StartDate { get; }
    [JsonPropertyName("State")] public string State { get; }
    [JsonPropertyName("Tags")] public string Tags { get; }
    [JsonPropertyName("TargetDate")] public DateTime? TargetDate { get; }
    [JsonPropertyName("TimeCriticality")] public long? TimeCriticality { get; }
    [JsonPropertyName("Title")] public string Title { get; }
    [JsonPropertyName("Violation")] public string? Violation { get; }
    [JsonPropertyName("WeightedShortestJobFirst")] public long? WeightedShortestJobFirst { get; }
    [JsonPropertyName("WorkItemType")] public string WorkItemType { get; }

}

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem))]
internal partial class WorkItemSourceGenerationContext : JsonSerializerContext
{
}

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem[]))]
internal partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext
{
}