using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entities.DTO;

namespace Entities.Contracts
{
	[Table("exams")]
	public class Exam
	{
		[Key]
		[Column("id")]
		public Guid Id { get; set; }

		[Required]
		[Column("title")]
		[StringLength(255)]
		public string Title { get; set; }

		[Column("description")]
		public string Description { get; set; }

		[Column("subject_id")]
		public Guid SubjectId { get; set; }
		[ForeignKey(nameof(SubjectId))]
		public virtual Subject Subject { get; set; }

		[Required]
		[Column("exam_struct_id")]
		[ForeignKey(nameof(ExamStruct))]
		public Guid ExamStructId { get; set; }
		public virtual ExamQuestion ExamStruct { get; set; }

		[Column("exam_type_id")]
		public Guid ExamTypeId { get; set; }
		[ForeignKey(nameof(ExamTypeId))]
		public virtual ExamType ExamType { get; set; }

		[Column("created_by")]
		public Guid CreatorId { get; set; }
		[ForeignKey(nameof(CreatorId))]
		public virtual User Creator { get; set; }

		[Required]
		[Column("due_date")]
		public DateTime DueDate { get; set; }

		[Column("total_points")]
		public byte TotalQuestions { get; set; }

		[Column("score")]
		public float Score { get; set; }

		[Column("name")]
		public string Name { get; set; } = string.Empty;

		[Column("created_at")]
		public DateTime CreatedAt { get; set; }

		[Column("updated_at")]
		public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;

		[Column("deleted")]
		public bool IsDeleted { get; set; } = false;


		[InverseProperty(nameof(ExamAttachment.Exam))]
		public virtual ICollection<ExamAttachment> ExamAttachments { get; set; }
		[InverseProperty(nameof(Submission.Exam))]
		public virtual ICollection<Submission> Submissions { get; set; }

		public Exam()
		{
			Id = Guid.NewGuid();

			ExamAttachments = new HashSet<ExamAttachment>();
			Submissions = new HashSet<Submission>();
		}
	}


	public static class examExt
	{
		public static Submission ConvertToSubmission(this Exam exam, Guid studentId, Guid GraderId, Guid classId)
		{
			if (exam == null) return new Submission();
			var submission = new Submission();

			submission.StudentId = studentId;
			submission.SubmissionTime = DateTime.Now;
			submission.Status = SubmissionStatus.Pending;
			submission.GraderId = GraderId;
			submission.ExamId = exam.Id;
			submission.ClassId = classId;
			ConvertExamSturctToSubmissionDetails(exam.ExamStruct, studentId, submission.SubmissionDetails);

			return submission;
		}


		public static void ConvertExamSturctToSubmissionDetails(ExamQuestion examStruct, Guid studentId, ICollection<SubmissionDetail> submissions)
		{
			if (examStruct == null) return;
			submissions.Add(new SubmissionDetail
			{
				StudentId = studentId,
				ExamQuestionId = examStruct.Id,
				CreatedAt = DateTime.Now,
				UpdatedAt = DateTime.Now,
			});

			examStruct.ChildExamQuestions?.ToList().ForEach(s =>
			{
				ConvertExamSturctToSubmissionDetails(s, studentId, submissions);
			});
		}
	}
}
