package com.nebula.erp.product.service;

import com.nebula.erp.product.model.Brand;
import com.nebula.erp.product.model.Product;
import com.nebula.erp.product.repository.BrandRepository;
import com.nebula.erp.product.repository.ProductRepository;
import com.nebula.erp.product.requestmodel.BrandRequest;
import com.nebula.erp.product.utility.CreateLogger;
import com.nebula.erp.product.utility.JwtRequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import com.nebula.erp.product.service.S3Service;
import org.springframework.data.domain.Sort;

@Service
public class BrandService {

    @Autowired
    private S3Service s3Service;

    @Autowired
    private BrandRepository brandRepository;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private JwtRequestUtils jwtRequestUtils;

    @Value("${image.upload.dir}")
    private String imageUploadDir;

    @Value("${image.storage.location}")
    private String imageStorageLocation;

    @Autowired
    private CreateLogger createLogger;

    private static final String path = "/brands";

   public Page<Brand> getAllBrand(int page, int size, String search) {

    Pageable pageable = PageRequest.of(
            page - 1,
            size,
            Sort.by(Sort.Direction.DESC, "created_at")
    );

    String tenantName = jwtRequestUtils.getTenantName();

    if (search == null || search.trim().isEmpty()) {
        return brandRepository.findAllByTenant(pageable, tenantName);
    }

    String keyword = "%" + search.toLowerCase() + "%";

    return brandRepository.searchBrands(tenantName, keyword, pageable);
}

    public Brand createBrand(BrandRequest brandRequest, MultipartFile brandImage) throws IOException {
        // Validate required fields
        if (brandRequest.getName() == null || brandRequest.getName().isEmpty()) {
            throw new IllegalArgumentException("Brand name is required");
        }

        String tenantName = jwtRequestUtils.getTenantName();
        String userId = jwtRequestUtils.getUserId();

        // Create a new Brand object
        Brand brand = new Brand();
        brand.setName(brandRequest.getName());
        brand.setDescription(brandRequest.getDescription());
        brand.setCreated_by(userId);
        brand.setTenant(tenantName);

        // Save image if provided
        if (brandImage != null && !brandImage.isEmpty()) {
            // Check if the file is an image
            String contentType = brandImage.getContentType();
            if (!isValidImage(contentType)) {
                createLogger.createLogger("error", path, "POST", "Invalid image format. Only JPEG, PNG are allowed.", "");
                throw new IllegalArgumentException("Invalid image format. Only JPEG, PNG are allowed.");
            }
            String imagePath = null;
            if("local".equalsIgnoreCase(imageStorageLocation)) {
                imagePath = saveImage(brandImage);
            } else if("aws".equalsIgnoreCase(imageStorageLocation)) {
                imagePath = s3Service.uploadFile(brandImage, tenantName);
            } else {
                imagePath = saveImage(brandImage);
            }
            brand.setImage(imagePath);
        }

        return brandRepository.save(brand);
    }

    public Optional<Brand> getBrand(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();
        return brandRepository.findByIdAndTenant(id, tenantName);
    }

    public Brand updateBrand(Long id, BrandRequest brandRequest, Object brandImage) throws IOException {
        String tenantName = jwtRequestUtils.getTenantName();

        // Find the existing Brand
        Brand brand = brandRepository.findByIdAndTenant(id, tenantName).orElseThrow(() -> new RuntimeException("Brand not found"));

        // Update the Brand details
        brand.setName(brandRequest.getName());
        brand.setDescription(brandRequest.getDescription());

        // Save image if provided
        // Handle image file for update (optional)
        if (brandImage instanceof MultipartFile) {
            MultipartFile file = (MultipartFile) brandImage;
            if (file != null && !file.isEmpty()) {
                // Check if the file is an image
                String contentType = file.getContentType();
                if (!isValidImage(contentType)) {
                    createLogger.createLogger("error", path, "PUT", "Invalid image format. Only JPEG, PNG are allowed.", "");
                    throw new IllegalArgumentException("Invalid image format. Only JPEG, PNG are allowed.");
                }

                String imagePath = null;
                if("local".equalsIgnoreCase(imageStorageLocation)) {
                    if(brand.getImage() != null){
                        String oldImage = brand.getImage();
                        File oldFile = new File(oldImage);
                        if (oldFile.exists()) {
                            oldFile.delete();  // Delete the old image
                        }
                    }
                    imagePath = saveImage(file);
                } else if("aws".equalsIgnoreCase(imageStorageLocation)) {
                    if (brand.getImage() != null){
                        s3Service.deleteFileFroms3bucket(brand.getImage());
                    }
                    imagePath = s3Service.uploadFile(file, tenantName);
                }

                brand.setImage(imagePath);
            }
        } else {
            if(brandImage != null && !Objects.equals(brandImage.toString(), "")){
            }else if(brandImage != null && Objects.equals(brandImage.toString(), "")){
                if("local".equalsIgnoreCase(imageStorageLocation)) {
                    // Remove the existing image
                    if (brand.getImage() != null) {
                        String oldImage = brand.getImage();
                        File oldFile = new File(oldImage);
                        if (oldFile.exists()) {
                            oldFile.delete();  // Delete the old image
                        }
                    }
                } else if("aws".equalsIgnoreCase(imageStorageLocation)) {
                    if (brand.getImage() != null){
                        s3Service.deleteFileFroms3bucket(brand.getImage());
                    }
                }
                brand.setImage(null);
            }else{
            }
        }

        // Save and return the updated brand
        return brandRepository.save(brand);
    }

    public void deleteBrand(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();

        Brand brand = brandRepository.findByIdAndTenant(id, tenantName).orElseThrow(() -> new RuntimeException("Brand not found"));

        // Check if there are any products associated with the brand
        List<Product> associatedProducts = productRepository.findProductsByBrandId(id);
        if (!associatedProducts.isEmpty()) {
            createLogger.createLogger("error", path, "DELETE", "Cannot delete brand because it is associated with one or more products", "");
            throw new RuntimeException("Cannot delete brand because it is associated with one or more products");
        }

        if("local".equalsIgnoreCase(imageStorageLocation)) {
            if (brand.getImage() != null) {
                String oldImage = brand.getImage();
                File oldFile = new File(oldImage);
                if (oldFile.exists()) {
                    oldFile.delete();  // Delete the old image
                }
            }
        } else if("aws".equalsIgnoreCase(imageStorageLocation)) {
            if (brand.getImage() != null){
                s3Service.deleteFileFroms3bucket(brand.getImage());
            }
        }

        brandRepository.deleteById(id);
    }

    // Helper method to save image
    private String saveImage(MultipartFile image) throws IOException {
        // Get the original filename
        String originalFilename = image.getOriginalFilename();
        // Generate a unique filename
        String uniqueFilename = UUID.randomUUID().toString() + "_" + originalFilename;
        // Define the file path to save the image
        Path imagePath = Paths.get(imageUploadDir, uniqueFilename);

        // Ensure directory exists
        Files.createDirectories(imagePath.getParent());

        // Write the file to the file system
        Files.write(imagePath, image.getBytes());

        // Return the path to store in the database
        return imagePath.toString();
    }

    // Helper method to validate image format
    private boolean isValidImage(String contentType) {
        return contentType != null && (contentType.equals("image/jpeg") || contentType.equals("image/png"));
    }

}