using System;
using System.Collections.Generic;
using EventsAppQuest.Web.Core;
using EventsAppQuest.Web.Domain;

namespace EventsAppQuest.Web.Application
{
    /// <summary>
    /// Implementação mock: dados em memória para a camada Web (coerentes entre si).
    /// Pipeline comercial e sessões Quest associadas; follow-ups pendentes e concluídos.
    /// </summary>
    public class MockWebDataService : IMockWebDataService
    {
        private readonly List<WebLead> _leads = new List<WebLead>();
        private readonly List<SalesOpportunity> _opportunities = new List<SalesOpportunity>();
        private readonly List<ProposalRecord> _proposals = new List<ProposalRecord>();
        private readonly List<SessionRecord> _sessions = new List<SessionRecord>();
        private readonly List<FollowUpTask> _followUps = new List<FollowUpTask>();

        /// <summary>Construtor padrão: semeia dados demo (comportamento existente).</summary>
        public MockWebDataService()
        {
            SeedMockData();
        }

        /// <summary>Construtor para instalador: seedDemo = true popula dados de demonstração; false deixa listas vazias.</summary>
        public MockWebDataService(bool seedDemo)
        {
            if (seedDemo)
                SeedMockData();
        }

        private void SeedMockData()
        {
            var now = DateTime.UtcNow;

            // Leads
            var lead1 = new WebLead { Id = "lead-1", Name = "Maria Silva", Email = "maria.silva@empresa.pt", Phone = "+351 912 000 001", Company = "Empresa PT", Status = LeadStatus.Qualified, Source = "Website", CreatedAt = now.AddDays(-14), Notes = "Interesse em evento corporativo 80 pax." };
            var lead2 = new WebLead { Id = "lead-2", Name = "João Santos", Email = "joao@eventos.pt", Phone = "+351 913 000 002", Company = "Eventos & Cia", Status = LeadStatus.Contacted, Source = "Referral", CreatedAt = now.AddDays(-7), Notes = "" };
            var lead3 = new WebLead { Id = "lead-3", Name = "Ana Costa", Email = "ana.costa@hotel.pt", Phone = "+351 914 000 003", Company = "Hotel Vista", Status = LeadStatus.New, Source = "Inbound", CreatedAt = now.AddDays(-2), Notes = "Pedido de proposta recebido." };
            var lead4 = new WebLead { Id = "lead-4", Name = "Pedro Ferreira", Email = "pedro@startup.pt", Phone = "+351 915 000 004", Company = "Startup Labs", Status = LeadStatus.New, Source = "Website", CreatedAt = now.AddDays(-1), Notes = "Evento tech 50 pax." };
            _leads.AddRange(new[] { lead1, lead2, lead3, lead4 });

            // Proposals (criar antes de oportunidades que as referenciam)
            var prop1 = new ProposalRecord { Id = "prop-1", OpportunityId = "opp-1", Name = "Proposta Premium - Empresa PT", Status = ProposalRecordStatus.Sent, SentAt = now.AddDays(-3), ViewedAt = now.AddDays(-2), AcceptedAt = null };
            var prop2 = new ProposalRecord { Id = "prop-2", OpportunityId = "opp-2", Name = "Proposta Casamento 120 pax", Status = ProposalRecordStatus.Draft, SentAt = null, ViewedAt = null, AcceptedAt = null };
            var prop3 = new ProposalRecord { Id = "prop-3", OpportunityId = "opp-3", Name = "Proposta Corporativo Ana Costa", Status = ProposalRecordStatus.Sent, SentAt = now.AddDays(-5), ViewedAt = null, AcceptedAt = null };
            var prop4 = new ProposalRecord { Id = "prop-4", OpportunityId = "opp-4", Name = "Proposta Startup Labs", Status = ProposalRecordStatus.Draft, SentAt = null, ViewedAt = null, AcceptedAt = null };
            var prop5 = new ProposalRecord { Id = "prop-5", OpportunityId = "opp-5", Name = "Proposta Aniversário Eventos & Cia", Status = ProposalRecordStatus.Sent, SentAt = now.AddDays(-2), ViewedAt = null, AcceptedAt = null };
            _proposals.AddRange(new[] { prop1, prop2, prop3, prop4, prop5 });

            // Sessions (algumas com sessão Quest feita, outras não)
            var sess1Time = now.AddDays(-1);
            var sess1 = new SessionRecord
            {
                Id = "sess-1", SessionId = "quest-session-001", OpportunityId = "opp-1", ProposalRecordId = "prop-1",
                RecommendedProposalId = "proposal-guid-1", SelectedProposalId = "proposal-guid-1",
                FinalDecisionState = WebSessionDecisionState.Interested, ConfirmedCTA = "Agendar reunião",
                SuggestedNextAction = "Enviar detalhes do pacote premium", FollowUpPriority = FollowUpPriority.High,
                HasExportPayload = true, HasHandoffReport = true, HasShareableSummary = true, HasQualityAssessment = true, HasImprovementPlan = true,
                LastSessionTimestamp = sess1Time, HeldAt = sess1Time, CreatedAt = sess1Time
            };
            var sess2 = new SessionRecord
            {
                Id = "sess-2", SessionId = null, OpportunityId = "opp-2", ProposalRecordId = null,
                RecommendedProposalId = null, SelectedProposalId = null, FinalDecisionState = WebSessionDecisionState.Unknown,
                ConfirmedCTA = null, SuggestedNextAction = "Agendar sessão Quest", FollowUpPriority = FollowUpPriority.Medium,
                HasExportPayload = false, HasHandoffReport = false, HasShareableSummary = false, HasQualityAssessment = false, HasImprovementPlan = false,
                LastSessionTimestamp = null, HeldAt = null, CreatedAt = now.AddDays(-4)
            };
            var sess3Time = now.AddDays(-2);
            var sess3 = new SessionRecord
            {
                Id = "sess-3", SessionId = "quest-session-003", OpportunityId = "opp-3", ProposalRecordId = "prop-3",
                RecommendedProposalId = "proposal-guid-3", SelectedProposalId = "proposal-guid-3",
                FinalDecisionState = WebSessionDecisionState.ReadyToClose, ConfirmedCTA = "Fechar contrato",
                SuggestedNextAction = "Enviar minuta e agendar assinatura", FollowUpPriority = FollowUpPriority.Urgent,
                HasExportPayload = true, HasHandoffReport = true, HasShareableSummary = true, HasQualityAssessment = true, HasImprovementPlan = false,
                LastSessionTimestamp = sess3Time, HeldAt = sess3Time, CreatedAt = sess3Time
            };
            _sessions.AddRange(new[] { sess1, sess2, sess3 });

            // Oportunidades: usar estágios do pipeline (NewLead, Contacted, ProposalSent, QuestSessionDone, FollowUp, ReadyToClose, Won, Lost)
            var opp1 = new SalesOpportunity
            {
                Id = "opp-1", LeadId = lead1.Id, Title = "Evento corporativo 80 pax - Empresa PT",
                Stage = OpportunityStage.QuestSessionDone, Value = 25000f, ProposalRecordId = "prop-1", SessionRecordId = "sess-1",
                CommercialPriority = CommercialPriority.High, SuggestedNextAction = "Enviar detalhes do pacote premium",
                CreatedAt = now.AddDays(-10), UpdatedAt = now.AddDays(-1)
            };
            var opp2 = new SalesOpportunity
            {
                Id = "opp-2", LeadId = lead2.Id, Title = "Casamento 120 convidados",
                Stage = OpportunityStage.Contacted, Value = 35000f, ProposalRecordId = null, SessionRecordId = null,
                CommercialPriority = CommercialPriority.Medium, SuggestedNextAction = "Enviar proposta e agendar visita",
                CreatedAt = now.AddDays(-5), UpdatedAt = now.AddDays(-2)
            };
            var opp3 = new SalesOpportunity
            {
                Id = "opp-3", LeadId = lead3.Id, Title = "Corporativo Ana Costa - Hotel Vista",
                Stage = OpportunityStage.ReadyToClose, Value = 18000f, ProposalRecordId = "prop-3", SessionRecordId = "sess-3",
                CommercialPriority = CommercialPriority.Critical, SuggestedNextAction = "Enviar minuta e agendar assinatura",
                CreatedAt = now.AddDays(-8), UpdatedAt = now.AddDays(-2)
            };
            var opp4 = new SalesOpportunity
            {
                Id = "opp-4", LeadId = lead4.Id, Title = "Evento tech 50 pax - Startup Labs",
                Stage = OpportunityStage.NewLead, Value = 8000f, ProposalRecordId = null, SessionRecordId = null,
                CommercialPriority = CommercialPriority.Low, SuggestedNextAction = "Qualificar e enviar proposta inicial",
                CreatedAt = now.AddDays(-1), UpdatedAt = now
            };
            var opp5 = new SalesOpportunity
            {
                Id = "opp-5", LeadId = lead2.Id, Title = "Aniversário empresarial Eventos & Cia",
                Stage = OpportunityStage.ProposalSent, Value = 12000f, ProposalRecordId = "prop-5", SessionRecordId = null,
                CommercialPriority = CommercialPriority.Medium, SuggestedNextAction = "Aguardar feedback; sugerir sessão Quest",
                CreatedAt = now.AddDays(-4), UpdatedAt = now.AddDays(-1)
            };
            var opp6 = new SalesOpportunity
            {
                Id = "opp-6", LeadId = lead1.Id, Title = "Follow-up pós-sessão Empresa PT",
                Stage = OpportunityStage.FollowUp, Value = 25000f, ProposalRecordId = "prop-1", SessionRecordId = "sess-1",
                CommercialPriority = CommercialPriority.High, SuggestedNextAction = "Ligar para confirmar reunião",
                CreatedAt = now.AddDays(-10), UpdatedAt = now
            };
            var opp7 = new SalesOpportunity
            {
                Id = "opp-7", LeadId = lead3.Id, Title = "Evento fechado Q1 - Hotel Vista",
                Stage = OpportunityStage.Won, Value = 18000f, ProposalRecordId = "prop-3", SessionRecordId = "sess-3",
                CommercialPriority = CommercialPriority.Low, SuggestedNextAction = "Entregar evento",
                CreatedAt = now.AddDays(-30), UpdatedAt = now.AddDays(-3)
            };
            _opportunities.AddRange(new[] { opp1, opp2, opp3, opp4, opp5, opp6, opp7 });

            // Follow-ups: pendentes e concluídos
            _followUps.Add(new FollowUpTask { Id = "fu-1", OpportunityId = opp1.Id, SessionRecordId = sess1.Id, Title = "Enviar detalhes do pacote premium", DueDate = now.AddDays(2), Priority = FollowUpPriority.High, IsCompleted = false, CreatedAt = now.AddDays(-1) });
            _followUps.Add(new FollowUpTask { Id = "fu-2", OpportunityId = opp2.Id, SessionRecordId = null, Title = "Agendar sessão Quest para apresentação", DueDate = now.AddDays(5), Priority = FollowUpPriority.Medium, IsCompleted = false, CreatedAt = now.AddDays(-2) });
            _followUps.Add(new FollowUpTask { Id = "fu-3", OpportunityId = opp3.Id, SessionRecordId = sess3.Id, Title = "Enviar minuta e agendar assinatura", DueDate = now.AddDays(1), Priority = FollowUpPriority.Urgent, IsCompleted = false, CreatedAt = now.AddDays(-2) });
            _followUps.Add(new FollowUpTask { Id = "fu-4", OpportunityId = opp1.Id, SessionRecordId = sess1.Id, Title = "Ligar para confirmar reunião", DueDate = now.AddDays(-1), Priority = FollowUpPriority.High, IsCompleted = true, CreatedAt = now.AddDays(-3) });
            _followUps.Add(new FollowUpTask { Id = "fu-5", OpportunityId = opp4.Id, SessionRecordId = null, Title = "Qualificar lead e enviar proposta inicial", DueDate = now.AddDays(7), Priority = FollowUpPriority.Low, IsCompleted = false, CreatedAt = now });
        }

        public IReadOnlyList<WebLead> GetLeads() => _leads;
        public IReadOnlyList<SalesOpportunity> GetOpportunities() => _opportunities;
        public IReadOnlyList<ProposalRecord> GetProposals() => _proposals;
        public IReadOnlyList<SessionRecord> GetSessions() => _sessions;
        public IReadOnlyList<FollowUpTask> GetFollowUpTasks() => _followUps;

        public (string sessionRecordId, IReadOnlyList<string> indicators) ApplyQuestSessionToOpportunity(QuestSessionSnapshot snapshot, string opportunityId)
        {
            var opp = _opportunities.Find(o => o.Id == opportunityId);
            if (opp == null)
                return (null, new List<string>());

            QuestSessionToCRMMapper.MapToSessionAndOpportunity(snapshot, opportunityId, opp.ProposalRecordId,
                out var sessionRecord, out var suggestedStage, out var indicators);

            _sessions.Add(sessionRecord);
            opp.SessionRecordId = sessionRecord.Id;
            opp.SuggestedNextAction = snapshot.SuggestedNextAction;
            opp.UpdatedAt = DateTime.UtcNow;
            if (suggestedStage.HasValue)
                opp.Stage = suggestedStage.Value;
            opp.LastQuestSessionId = snapshot.SessionId;
            opp.LastQuestDecisionState = snapshot.FinalDecisionState;
            opp.LastQuestCTA = snapshot.ConfirmedCTA;
            opp.LastQuestNextAction = snapshot.SuggestedNextAction;
            opp.LastQuestFollowUpPriority = snapshot.FollowUpPriority;
            opp.LastQuestEngagementLabel = snapshot.EngagementLabel;
            opp.LastQuestQualityLabel = snapshot.QualityLabel;
            opp.LastQuestSummary = snapshot.OutcomeSummary;
            opp.LastQuestRecommendedProposalId = snapshot.RecommendedProposalId;
            opp.LastQuestSelectedProposalId = snapshot.SelectedProposalId;

            return (sessionRecord.Id, indicators);
        }

        public void MarkOpportunityOrderCycleClosed(string opportunityId)
        {
            if (string.IsNullOrEmpty(opportunityId)) return;
            var opp = _opportunities.Find(o => o.Id == opportunityId);
            if (opp == null) return;
            opp.Stage = OpportunityStage.Won;
            opp.UpdatedAt = DateTime.UtcNow;
        }
    }
}
