using LSFE.MobApp.Contracts;
using LSFE.MobApp.Contracts.Doctor;
using LSFE.MobApp.DTO.DoctorDto;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LSFE.MobApp.Services.Doctor
{
    public class DoctorService : IDoctorService
    {
        private readonly IQueryService _queryService;
        private readonly Repository<Entities.Doctor.Doctor> _doctorRepository;
        private readonly ILogger<DoctorService> _logger;

        public DoctorService(
            IQueryService queryService,
            Repository<Entities.Doctor.Doctor> doctorRepository,
            ILogger<DoctorService> logger)
        {
            _queryService = queryService;
            _doctorRepository = doctorRepository;
            _logger = logger;
        }

        // Basic fetch using repository (simple queries)
        public async Task<List<Entities.Doctor.Doctor>> GetAllDoctorsAsync()
        {
            return await _doctorRepository.GetAllAsync();
        }

        public async Task<List<Entities.Doctor.Doctor>> GetActiveDoctorsAsync()
        {
            return await _doctorRepository.GetActiveAsync();
        }

        // Complex queries using IQueryService
        public async Task<List<DoctorWithInstitution>> GetDoctorsWithInstitutionsAsync()
        {
            try
            {
                var query = @"
                SELECT 
                    d.DoctorId,
                    d.DoctorName,
                    d.Specialization,
                    d.InstitutionId,
                    i.InstitutionName,
                    d.IsActive,
                    d.CreatedDate
                FROM Doctors d
                INNER JOIN Institutions i ON d.InstitutionId = i.InstitutionId
                WHERE d.IsActive = 1 AND i.IsActive = 1
                ORDER BY i.InstitutionName, d.DoctorName";

                return await _queryService.ExecuteQueryAsync<DoctorWithInstitution>(query);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching doctors with institutions");
                throw;
            }
        }

        public async Task<List<Entities.Doctor.Doctor>> GetDoctorsByInstitutionAsync(int institutionId)
        {
            try
            {
                var query = @"
                SELECT * FROM Doctors 
                WHERE InstitutionId = ? AND IsActive = 1
                ORDER BY DoctorName";

                return await _queryService.ExecuteQueryAsync<Entities.Doctor.Doctor>(query, institutionId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching doctors by institution {InstitutionId}", institutionId);
                throw;
            }
        }

        public async Task<List<Entities.Doctor.Doctor>> GetDoctorsBySpecializationAsync(string specialization)
        {
            try
            {
                var query = @"
                SELECT * FROM Doctors 
                WHERE Specialization LIKE ? AND IsActive = 1
                ORDER BY DoctorName";

                return await _queryService.ExecuteQueryAsync<Entities.Doctor.Doctor>(query, $"%{specialization}%");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching doctors by specialization {Specialization}", specialization);
                throw;
            }
        }

        public async Task<List<DoctorWithInstitution>> GetDoctorsByTerritoryAsync(int territoryId)
        {
            try
            {
                var query = @"
                SELECT 
                    d.DoctorId,
                    d.DoctorName,
                    d.Specialization,
                    d.InstitutionId,
                    i.InstitutionName,
                    d.IsActive,
                    d.CreatedDate,
                    t.TerritoryName
                FROM Doctors d
                INNER JOIN Institutions i ON d.InstitutionId = i.InstitutionId
                INNER JOIN Territories t ON i.TerritoryId = t.TerritoryId
                WHERE t.TerritoryId = ? AND d.IsActive = 1 AND i.IsActive = 1
                ORDER BY i.InstitutionName, d.DoctorName";

                return await _queryService.ExecuteQueryAsync<DoctorWithInstitution>(query, territoryId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching doctors by territory {TerritoryId}", territoryId);
                throw;
            }
        }

        public async Task<int> GetDoctorCountByInstitutionAsync(int institutionId)
        {
            try
            {
                var query = @"
                SELECT COUNT(*) as Count 
                FROM Doctors 
                WHERE InstitutionId = ? AND IsActive = 1";

                var result = await _queryService.ExecuteQueryAsync<CountResult>(query, institutionId);
                return result.FirstOrDefault()?.Count ?? 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error counting doctors by institution {InstitutionId}", institutionId);
                throw;
            }
        }

        // Helper class for count queries
        private class CountResult
        {
            public int Count { get; set; }
        }
    }
}
