using Lada.Framework.Data.Domains.Crm;
using Lada.Framework.Data.Domains.Finance;
using Lada.Framework.Data.Domains.Medias;
using Lada.Framework.Data.Enums;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.Infrastructures;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Finance;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finance;
using Ladaer.BackEnd.Infrastructures.DTO.Profiles;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Finance;
using Ladaer.BackEnd.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.Services.Identity;
using Microsoft.EntityFrameworkCore;

namespace Ladaer.BackEnd.Infrastructures.Services.Finance
{
    /// <summary>
    /// Interface dịch vụ quản lý hóa đơn thuế
    /// </summary>
    public interface ITaxInvoiceService
    {
        Task<TaxInvoiceResult> CreateTaxInvoiceAsync(CreateTaxInvoiceModel model, CurrentUser currentUser);
        Task<TaxInvoiceResult> UpdateTaxInvoiceStatusAsync(UpdateTaxInvoiceStatusModel model, CurrentUser currentUser);
        Task<TaxInvoiceItem?> GetTaxInvoiceByIdAsync(int id, CurrentUser currentUser);
        Task<TaxInvoiceItem?> GetTaxInvoiceBySlipIdAsync(int slipId, CurrentUser currentUser);
        Task<BaseResult> DeleteTaxInvoiceAsync(int id, CurrentUser currentUser);
    }

    /// <summary>
    /// Dịch vụ quản lý hóa đơn thuế
    /// </summary>
    public class TaxInvoiceService : ITaxInvoiceService
    {
        private readonly IRepository<TaxInvoice> _taxInvoiceRepository;
        private readonly IRepository<CustomerReconciliationSlip> _slipRepository;
        private readonly IRepository<VatInfo> _vatInfoRepository;
        private readonly IRepository<Media> _mediaRepository;
        private readonly IDocumentService _documentService;
        private readonly IAppConfigService _appConfigService;
        private readonly IUserService _userService;

        public TaxInvoiceService(
            IRepository<TaxInvoice> taxInvoiceRepository,
            IRepository<CustomerReconciliationSlip> slipRepository,
            IRepository<VatInfo> vatInfoRepository,
            IRepository<Media> mediaRepository,
            IDocumentService documentService,
            IAppConfigService appConfigService,
            IUserService userService)
        {
            _taxInvoiceRepository = taxInvoiceRepository;
            _slipRepository = slipRepository;
            _vatInfoRepository = vatInfoRepository;
            _mediaRepository = mediaRepository;
            _documentService = documentService;
            _appConfigService = appConfigService;
            _userService = userService;
        }

        /// <summary>
        /// Tạo hóa đơn thuế mới
        /// </summary>
        public async Task<TaxInvoiceResult> CreateTaxInvoiceAsync(CreateTaxInvoiceModel model, CurrentUser currentUser)
        {
            var result = new TaxInvoiceResult();

            try
            {
                // Validate model
                var validationErrors = model.Validate();
                if (validationErrors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = string.Join("; ", validationErrors);
                    return result;
                }

                // Validate reconciliation slip exists and is Approved/Completed
                var slip = await _slipRepository.Query()
                    .Include(x => x.Customer)
                    .FirstOrDefaultAsync(x => x.Id == model.CustomerReconciliationSlipId);

                if (slip == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Phiếu đối soát không tồn tại";
                    return result;
                }

                if (slip.Status != CustomerReconciliationSlipStatus.Approved &&
                    slip.Status != CustomerReconciliationSlipStatus.Completed)
                {
                    result.Result = Result.Failed;
                    result.Message = "Chỉ có thể tạo hóa đơn thuế cho phiếu đối soát đã được duyệt hoặc hoàn thành";
                    return result;
                }

                // Check if tax invoice already exists for this slip (chưa bị xóa)
                var existingTaxInvoice = await _taxInvoiceRepository.Query()
                    .FirstOrDefaultAsync(x => x.CustomerReconciliationSlipId == model.CustomerReconciliationSlipId
                                           && !x.IsDeleted);

                if (existingTaxInvoice != null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Phiếu đối soát này đã có hóa đơn thuế";
                    return result;
                }

                // Validate VatInfo belongs to the same customer
                var vatInfo = await _vatInfoRepository.Query()
                    .FirstOrDefaultAsync(x => x.Id == model.VatInfoId);

                if (vatInfo == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Thông tin VAT không tồn tại";
                    return result;
                }

                if (vatInfo.CustomerId != slip.CustomerId)
                {
                    result.Result = Result.Failed;
                    result.Message = "Thông tin VAT không thuộc khách hàng của phiếu đối soát";
                    return result;
                }

                // Calculate amounts - TotalFeeAmount đã bao gồm VAT
                // Cần tính ngược: Tổng cước chưa VAT = TotalFeeAmount / (1 + VAT%)
                decimal totalAmountIncludingVat = slip.TotalFeeAmount;

                // Lấy VAT rate từ cấu hình, mặc định 8%
                decimal vatRate = await GetVatRateAsync();

                // Tính tổng tiền chưa VAT (base amount)
                decimal totalAmount = totalAmountIncludingVat / (1 + vatRate / 100);

                // Tính VAT amount
                decimal vatAmount = totalAmountIncludingVat - totalAmount;

                // Create tax invoice
                var taxInvoice = new TaxInvoice
                {
                    CustomerReconciliationSlipId = model.CustomerReconciliationSlipId,
                    VatInfoId = model.VatInfoId,
                    Status = TaxInvoiceStatus.NotIssued,
                    TotalAmount = totalAmount,
                    VatRate = vatRate,
                    VatAmount = vatAmount,
                    TotalAmountIncludingVat = totalAmountIncludingVat,
                    Note = model.Note,
                    CreatedBy = currentUser.UserId,
                    CreatedByUserName = currentUser.UserName,
                    CreatedTime = DateTimeOffset.Now
                };

                await _taxInvoiceRepository.InsertAsync(taxInvoice);

                // Update slip with TaxInvoiceId
                slip.TaxInvoiceId = taxInvoice.Id;
                await _slipRepository.UpdateAsync(slip);

                result.Result = Result.Success;
                result.Message = "Tạo hóa đơn thuế thành công";
                result.TaxInvoiceId = taxInvoice.Id;
                result.Status = (int)taxInvoice.Status;
                result.StatusName = taxInvoice.Status.GetDescription();
            }
            catch (Microsoft.EntityFrameworkCore.DbUpdateException ex) when (ex.InnerException is Microsoft.Data.SqlClient.SqlException sqlEx && sqlEx.Number == 2601)
            {
                // Duplicate key error - phiếu đối soát đã có hóa đơn
                result.Result = Result.Failed;
                result.Message = "Phiếu đối soát này đã có hóa đơn thuế. Vui lòng kiểm tra lại.";
                return result;
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi tạo hóa đơn thuế: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Cập nhật trạng thái hóa đơn thuế
        /// </summary>
        public async Task<TaxInvoiceResult> UpdateTaxInvoiceStatusAsync(UpdateTaxInvoiceStatusModel model, CurrentUser currentUser)
        {
            var result = new TaxInvoiceResult();

            try
            {
                // Validate model
                var validationErrors = model.Validate();
                if (validationErrors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = string.Join("; ", validationErrors);
                    return result;
                }

                // Get tax invoice (chưa bị xóa)
                var taxInvoice = await _taxInvoiceRepository.Query()
                    .Include(x => x.CustomerReconciliationSlip)
                    .Include(x => x.VatInfo)
                    .FirstOrDefaultAsync(x => x.Id == model.TaxInvoiceId && !x.IsDeleted);

                if (taxInvoice == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Hóa đơn thuế không tồn tại";
                    return result;
                }

                // Validate status transition
                var newStatus = (TaxInvoiceStatus)model.Status;
                if (!IsValidStatusTransition(taxInvoice.Status, newStatus))
                {
                    result.Result = Result.Failed;
                    result.Message = $"Không thể chuyển từ trạng thái {taxInvoice.Status.GetDescription()} sang {newStatus.GetDescription()}";
                    return result;
                }

                // Process and save PDF file for Draft/Issued status
                if (newStatus >= TaxInvoiceStatus.Draft)
                {
                    if (model.Files == null || model.Files.Count == 0)
                    {
                        result.Result = Result.Failed;
                        result.Message = "Cần upload file PDF hóa đơn";
                        return result;
                    }

                    var pdfFile = model.Files[0];

                    // Use DocumentService to process and save PDF
                    var documentOptions = new Lada.Framework.DTO.Models.Media.DocumentSaveOptions
                    {
                        DocumentType = DocumentType.TaxInvoice,
                        DocumentFormat = DocumentFormat.PDF,
                        SaveToDatabase = true,
                        AltText = $"Hóa đơn thuế - {model.InvoiceNumber}",
                        Caption = $"File PDF hóa đơn thuế số {model.InvoiceNumber}",
                        DisplayOrder = 1,
                        CreatedBy = currentUser.UserId,
                        CreatedByUserName = currentUser.UserName,
                        UpdatedBy = currentUser.UserId,
                        UpdatedByUserName = currentUser.UserName
                    };

                    var documentResult = await _documentService.ProcessAndSaveAsync(pdfFile, documentOptions);

                    if (documentResult.Result != Result.Success)
                    {
                        result.Result = Result.Failed;
                        result.Message = $"Lỗi lưu file PDF: {documentResult.Message}";
                        return result;
                    }

                    // Update tax invoice with media
                    taxInvoice.MediaId = documentResult.MediaId;
                }

                // Update tax invoice
                taxInvoice.Status = newStatus;
                taxInvoice.InvoiceNumber = model.InvoiceNumber;
                taxInvoice.InvoiceDate = model.InvoiceDate;
                taxInvoice.UpdatedBy = currentUser.UserId;
                taxInvoice.UpdatedByUserName = currentUser.UserName;
                taxInvoice.UpdatedTime = DateTimeOffset.Now;

                await _taxInvoiceRepository.UpdateAsync(taxInvoice);

                result.Result = Result.Success;
                result.Message = "Cập nhật trạng thái hóa đơn thuế thành công";
                result.TaxInvoiceId = taxInvoice.Id;
                result.InvoiceNumber = taxInvoice.InvoiceNumber;
                result.Status = (int)taxInvoice.Status;
                result.StatusName = taxInvoice.Status.GetDescription();
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi cập nhật trạng thái hóa đơn thuế: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Lấy thông tin hóa đơn thuế theo ID
        /// </summary>
        public async Task<TaxInvoiceItem?> GetTaxInvoiceByIdAsync(int id, CurrentUser currentUser)
        {
            var taxInvoice = await _taxInvoiceRepository.Query()
                .Include(x => x.CustomerReconciliationSlip)
                .Include(x => x.VatInfo)
                .Include(x => x.Media)
                .FirstOrDefaultAsync(x => x.Id == id && !x.IsDeleted);

            if (taxInvoice == null)
                return null;

            var item = MapToItem(taxInvoice);

            // Set permission flags
            var userRoles = await _userService.GetRolesAsync(currentUser.UserId);
            item.CanUpdate = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase) ||
                                                 r.Equals("TaxInvoice.Update", StringComparison.OrdinalIgnoreCase));
            item.CanDelete = taxInvoice.Status == TaxInvoiceStatus.NotIssued || taxInvoice.Status == TaxInvoiceStatus.Draft;

            return item;
        }

        /// <summary>
        /// Lấy thông tin hóa đơn thuế theo ID phiếu đối soát
        /// </summary>
        public async Task<TaxInvoiceItem?> GetTaxInvoiceBySlipIdAsync(int slipId, CurrentUser currentUser)
        {
            var taxInvoice = await _taxInvoiceRepository.Query()
                .Include(x => x.CustomerReconciliationSlip)
                .Include(x => x.VatInfo)
                .Include(x => x.Media)
                .FirstOrDefaultAsync(x => x.CustomerReconciliationSlipId == slipId && !x.IsDeleted);

            if (taxInvoice == null)
                return null;

            var item = MapToItem(taxInvoice);

            // Set permission flags
            var userRoles = await _userService.GetRolesAsync(currentUser.UserId);
            item.CanUpdate = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase) ||
                                                 r.Equals("TaxInvoice.Update", StringComparison.OrdinalIgnoreCase));
            item.CanDelete = taxInvoice.Status == TaxInvoiceStatus.NotIssued || taxInvoice.Status == TaxInvoiceStatus.Draft;

            return item;
        }

        /// <summary>
        /// Xóa hóa đơn thuế (chỉ cho phép xóa khi ở trạng thái NotIssued)
        /// </summary>
        public async Task<BaseResult> DeleteTaxInvoiceAsync(int id, CurrentUser currentUser)
        {
            try
            {
                var taxInvoice = await _taxInvoiceRepository.Query()
                    .Include(x => x.CustomerReconciliationSlip)
                    .FirstOrDefaultAsync(x => x.Id == id && !x.IsDeleted);

                if (taxInvoice == null)
                {
                    return new BaseResult { Result = Result.Failed, Message = "Hóa đơn thuế không tồn tại" };
                }

                if (taxInvoice.Status != TaxInvoiceStatus.NotIssued)
                {
                    return new BaseResult { Result = Result.Failed, Message = "Chỉ có thể xóa hóa đơn thuế ở trạng thái Chưa xuất" };
                }

                // Update slip to remove TaxInvoiceId
                if (taxInvoice.CustomerReconciliationSlip != null)
                {
                    taxInvoice.CustomerReconciliationSlip.TaxInvoiceId = null;
                    await _slipRepository.UpdateAsync(taxInvoice.CustomerReconciliationSlip);
                }

                // Delete media if exists
                if (taxInvoice.MediaId.HasValue)
                {
                    var media = await _mediaRepository.GetByIdAsync(taxInvoice.MediaId.Value);
                    if (media != null)
                        await _mediaRepository.DeleteAsync(media);
                }

                await _taxInvoiceRepository.DeleteAsync(taxInvoice);

                return new BaseResult { Result = Result.Success, Message = "Xóa hóa đơn thuế thành công" };
            }
            catch (Exception ex)
            {
                return new BaseResult { Result = Result.SystemError, Message = $"Lỗi khi xóa hóa đơn thuế: {ex.Message}" };
            }
        }

        #region Private Methods

        /// <summary>
        /// Kiểm tra chuyển trạng thái hợp lệ
        /// </summary>
        private bool IsValidStatusTransition(TaxInvoiceStatus currentStatus, TaxInvoiceStatus newStatus)
        {
            return currentStatus switch
            {
                TaxInvoiceStatus.NotIssued => newStatus == TaxInvoiceStatus.Draft || newStatus == TaxInvoiceStatus.Issued,
                TaxInvoiceStatus.Draft => newStatus == TaxInvoiceStatus.Issued,
                TaxInvoiceStatus.Issued => false, // Cannot change from Issued
                _ => false
            };
        }

        /// <summary>
        /// Map entity sang item using AutoMapper
        /// </summary>
        private TaxInvoiceItem MapToItem(TaxInvoice taxInvoice)
        {
            var item = taxInvoice.ToItem();

            // Convert system path to URL
            if (!string.IsNullOrEmpty(item.PdfUrl))
            {
                item.PdfUrl = _documentService.GetUrlBySystemPath(item.PdfUrl).Result;
            }

            return item;
        }

        /// <summary>
        /// Lấy VAT rate từ cấu hình với fallback mặc định 8%
        /// </summary>
        private async Task<decimal> GetVatRateAsync()
        {
            try
            {
                var vatRateStr = await _appConfigService.GetConfigValueAsync("Finance.TaxInvoice.VatRate");
                if (!string.IsNullOrEmpty(vatRateStr) && decimal.TryParse(vatRateStr, out decimal vatRate))
                {
                    return vatRate;
                }
                return 8; // Default 8%
            }
            catch
            {
                return 8; // Default 8% nếu có lỗi
            }
        }

        #endregion
    }
}
