using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using survey_beta.DataBaseContext;
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Update;
using survey_beta.DTOs.Response;
using survey_beta.Models;
using AutoMapper;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using survey_beta.DTOs.Default;

public class SurveyService
{
    private readonly AppDbContext _context;
    private readonly IMapper _mapper;
    private readonly ResponsesService _responsesService;

    public SurveyService(AppDbContext context, IMapper mapper, ResponsesService responsesService)
    {
        _context = context;
        _mapper = mapper;
        _responsesService = responsesService;
    }
    public async Task<List<SurveyDto>> GetAllSurveysAsync(string id = null)
    {
        IQueryable<Survey> query = _context.Surveys.Include(s => s.Questions).ThenInclude(q =>q.Choices);

        if (!string.IsNullOrEmpty(id))
        {
            query = query.Where(s => s.Id == id);
        }

        var surveys = await query.ToListAsync();
        return _mapper.Map<List<SurveyDto>>(surveys);
    }
    public async Task<SurveyDto> CreateSurveyAsync(CreateSurveyDto request, string userId)
    {
        var survey = _mapper.Map<Survey>(request);
        survey.Id = Guid.NewGuid().ToString();
        survey.AuthorId = userId;

        _context.Surveys.Add(survey);
        await _context.SaveChangesAsync();

        return _mapper.Map<SurveyDto>(survey);
    }
    public async Task<bool> UpdateSurveyAsync(UpdateSurveyDto request)
    {
        var survey = await _context.Surveys
            .Include(s => s.Questions)
            .ThenInclude(q => q.Choices)
            .FirstOrDefaultAsync(s => s.Id == request.Id);

        if (survey == null) return false;
        if (survey.IsPublished)
        {
            throw new InvalidOperationException("Cannot update a published survey. Unpublish it first.");
        }
        survey.Title = request.Title != "string" ? request.Title : survey.Title;
        survey.Description = request.Description != "string" ? request.Description : survey.Description;
        survey.Category = request.Category != "string" ? request.Category : survey.Category;
        survey.ExpirationDate = request.ExpirationDate ?? survey.ExpirationDate;
        foreach (var updatedQuestion in request.Questions)
        {
            var existingQuestion = survey.Questions.FirstOrDefault(q => q.Id == updatedQuestion.Id);

            if (existingQuestion != null)
            {
                existingQuestion.Content = updatedQuestion.Content != "string" ? updatedQuestion.Content : existingQuestion.Content;
                existingQuestion.Type = updatedQuestion.QuestionType != "string" ? updatedQuestion.QuestionType : existingQuestion.Type;

                foreach (var updatedChoice in updatedQuestion.Choices)
                {
                    var existingChoice = existingQuestion.Choices.FirstOrDefault(c => c.Id == updatedChoice.Id);
                    if (existingChoice != null)
                    {
                        existingChoice.Letter = updatedChoice.Letter != "string" ? updatedChoice.Letter : existingChoice.Letter;
                        existingChoice.Content = updatedChoice.Content != "string" ? updatedChoice.Content : existingChoice.Content;
                    }
                }
            }
            else
            {
                survey.Questions.Add(new Question
                {
                    Content = updatedQuestion.Content,
                    Type = updatedQuestion.QuestionType,
                    SurveyId = survey.Id,
                    Choices = updatedQuestion.Choices.Select(c => new Choice
                    {
                        Letter = c.Letter,
                        Content = c.Content,
                    }).ToList()
                });
            }
        }
        survey.IsPublished = true;

        await _context.SaveChangesAsync();
        return true;
    }
    public async Task<bool> PublishSurveyAsync(string id)
    {
        var survey = await _context.Surveys.FindAsync(id);
        if (survey == null) return false;

        survey.IsPublished = true;
        await _context.SaveChangesAsync();
        return true;
    }

    public async Task<bool> UnpublishSurveyAsync(string id)
    {
        var survey = await _context.Surveys.FindAsync(id);
        if (survey == null) return false;

        survey.IsPublished = false;
        await _context.SaveChangesAsync();
        return true;
    }
    public async Task<bool> DeleteSurveyAsync(string id, CancellationToken cancellationToken)
    {
        var survey = await _context.Surveys
            .Include(s => s.Questions)
                .ThenInclude(q => q.Choices)
            .FirstOrDefaultAsync(s => s.Id == id, cancellationToken);

        if (survey == null) return false;

        _context.Surveys.Remove(survey);
        await _context.SaveChangesAsync(cancellationToken);
        return true;
    }
}
