using NetinaShop.Domain.CommandQueries.Commands;
using NetinaShop.Domain.Dtos.ScraperDtos.Response;
using NetinaShop.Domain.Dtos.SmallDtos;
using NetinaShop.Domain.Entities.Products;
using NetinaShop.Repository.Repositories.Base.Contracts;
using System.Linq;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using NetinaShop.Domain.Entities.Brands;
using NetinaShop.Domain.Entities.ProductCategories;

namespace NetinaShop.Infrastructure.Services.Scrapers;

public class DigikalaScraper : IDigikalaScraper
{
    private readonly IRestApiWrapper _apiWrapper;
    private readonly IRepositoryWrapper _repositoryWrapper;
    private readonly IMediator _mediator;
    private readonly IUploadFileService _uploadFileService;

    public DigikalaScraper(IRestApiWrapper apiWrapper, IRepositoryWrapper repositoryWrapper,IMediator mediator, IUploadFileService uploadFileService)
    {
        _apiWrapper = apiWrapper;
        _repositoryWrapper = repositoryWrapper;
        _mediator = mediator;
        _uploadFileService = uploadFileService;
    }
    public async Task<List<ScraperProductDto>> GetProductsByNameAsync(string productName)
    {
        var products = await _apiWrapper.DigikalaRestApi.SearchProductAsync(productName);
        return products.data.products.Select(s => new ScraperProductDto
        {
            PersianName = s.title_fa,
            EnglishName = s.title_en,
            MainImage = s.images.main.url.First(),
            //Cost = long.TryParse(s.default_variant.price.rrp_price,out long result) ? result : 0,
            ScraperId = s.id.ToString(),
            ScraperUrl = $"https://digikala.com/{s.url.uri}"
        }).ToList();
    }

    public async Task<bool> AddProductToShopAsync(string productId, string productName, CancellationToken cancellationToken = default)
    {
        var response = await _apiWrapper.DigikalaRestApi.GetProductAsync(productId);
        var digiProduct = response.data; var dbProduct = await _repositoryWrapper.SetRepository<Product>()
            .TableNoTracking
            .FirstOrDefaultAsync(p => p.PersianName.ToLower().Trim().Contains(productName.ToLower().Trim()), cancellationToken);
        var newSummery =  digiProduct.seo.description.Replace("فروشگاه اینترنتی دیجی\u200cکالا", "فروشگاه اینترنتی وسمه");
        if (dbProduct != null && !dbProduct.Summery.IsNullOrEmpty())
            newSummery = dbProduct.Summery;
        var specifications = new List<SpecificationSDto>();
        foreach (var specification in digiProduct.product.specifications)
        {
            foreach (var attribute in specification.attributes)
            {
                specifications.Add(new SpecificationSDto { Value = string.Join(",", attribute.values), Title = attribute.title });
            }
        }

        using var httClient = new HttpClient();
        var imageBytes = await httClient.GetByteArrayAsync(digiProduct.product.images.main.url.FirstOrDefault(), cancellationToken);
        var imageBase64 = Convert.ToBase64String(imageBytes);
        var uploadFile = new FileUploadRequest
        {
            StringBaseFile = imageBase64,
            FileName = digiProduct.product.title_fa.Replace(" ", "_") + ".jpg",
            FileUploadType = FileUploadType.Image,
            ContentType = "image/jpeg"
        };
        var uploadResponse = await _uploadFileService.UploadImageAsync(uploadFile);
        var files = new List<StorageFileSDto>
        {
            new StorageFileSDto
            {
                FileLocation = uploadResponse.FileLocation,
                FileName = uploadResponse.FileName,
                IsPrimary = true,
            }
        };
        if (dbProduct != null)
        {
            
            var request = new UpdateProductCommand(dbProduct.Id, digiProduct.product.title_fa, digiProduct.product.title_en,
                newSummery,
                dbProduct.ExpertCheck, dbProduct.Tags, dbProduct.Warranty, dbProduct.BeDisplayed, dbProduct.Cost,
                dbProduct.PackingCost, dbProduct.Stock, dbProduct.HasExpressDelivery
                , dbProduct.MaxOrderCount, false, dbProduct.BrandId, dbProduct.CategoryId, new DiscountSDto(), specifications, files);
            await _mediator.Send(request, cancellationToken);
        }
        else
        {
            var nonBrand = await _repositoryWrapper.SetRepository<Brand>()
                .TableNoTracking
                .FirstOrDefaultAsync(b => b.PersianName == "بدون برند", cancellationToken);
            if (nonBrand == null)
                throw new AppException("NoneBrand is not exist");

            var nonCat = await _repositoryWrapper.SetRepository<ProductCategory>()
                .TableNoTracking
                .FirstOrDefaultAsync(b => b.Name == "دسته بندی نشده", cancellationToken);
            if (nonCat == null)
                throw new AppException("NoneCategory is not exist");


            var request = new CreateProductCommand(productName, digiProduct.product.title_en,
                digiProduct.seo.description,
                string.Empty, string.Empty, string.Empty,true, 0,
                0, 0, false
                , 5, false, nonBrand.Id, nonCat.Id, new DiscountSDto(), specifications, files);
            await _mediator.Send(request, cancellationToken);
        }

        return true;
    }
}