package com.petshop.backend.service;

import com.petshop.backend.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.PostConstruct;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Locale;
import java.util.UUID;

@Service
public class AvatarStorageService {

    private static final String STORED_PREFIX = "/uploads/avatars/";
    private static final String BLOB_CONTAINER = "avatars";

    @Value("${app.upload.base-dir:uploads}")
    private String uploadBaseDir;

    @Autowired
    private AzureBlobService blobService;

    private Path avatarDirectory;

    @PostConstruct
    private void init() {
        avatarDirectory = Paths.get(uploadBaseDir, "avatars").toAbsolutePath().normalize();
    }

    public String storeAvatar(MultipartFile file) throws IOException {
        String extension = resolveExtension(file.getOriginalFilename());
        String filename = UUID.randomUUID() + extension;
        if (blobService.isEnabled()) {
            blobService.upload(BLOB_CONTAINER, filename, file.getBytes());
        } else {
            Files.createDirectories(avatarDirectory);
            Files.copy(file.getInputStream(), avatarDirectory.resolve(filename).normalize(), StandardCopyOption.REPLACE_EXISTING);
        }
        return STORED_PREFIX + filename;
    }

    public Resource loadAvatarResource(User user) {
        String filename = extractFilename(user.getAvatarUrl());
        if (blobService.isEnabled()) {
            return new ByteArrayResource(blobService.download(BLOB_CONTAINER, filename));
        }
        Path filePath = resolveStoredAvatarPath(user.getAvatarUrl());
        if (!Files.exists(filePath) || !Files.isRegularFile(filePath)) {
            throw new IllegalArgumentException("Avatar file was not found");
        }
        return new PathResource(filePath);
    }

    public void deleteAvatar(User user) throws IOException {
        if (user.getAvatarUrl() == null || user.getAvatarUrl().isBlank()) return;
        if (blobService.isEnabled()) {
            blobService.delete(BLOB_CONTAINER, extractFilename(user.getAvatarUrl()));
        } else {
            try {
                Files.deleteIfExists(resolveStoredAvatarPath(user.getAvatarUrl()));
            } catch (IllegalArgumentException ignored) {}
        }
    }

    private String extractFilename(String avatarUrl) {
        if (avatarUrl == null || !avatarUrl.startsWith(STORED_PREFIX)) throw new IllegalArgumentException("Avatar file was not found");
        return avatarUrl.substring(STORED_PREFIX.length());
    }

    public String toOwnerAvatarUrl(User user) {
        return hasAvatar(user) ? "/api/v1/users/" + user.getId() + "/avatar/file" : null;
    }

    public String toStoredAvatarUrl(String avatarFilenamePath) {
        return avatarFilenamePath;
    }

    public boolean hasAvatar(User user) {
        return user.getAvatarUrl() != null && !user.getAvatarUrl().isBlank();
    }

    public MediaType resolveMediaType(User user) {
        try {
            return MediaTypeFactory.getMediaType(loadAvatarResource(user)).orElse(MediaType.APPLICATION_OCTET_STREAM);
        } catch (IllegalArgumentException ex) {
            return MediaType.APPLICATION_OCTET_STREAM;
        }
    }

    private Path resolveStoredAvatarPath(String storedAvatarUrl) {
        if (storedAvatarUrl == null || storedAvatarUrl.isBlank() || !storedAvatarUrl.startsWith(STORED_PREFIX)) {
            throw new IllegalArgumentException("Avatar file was not found");
        }

        String filename = storedAvatarUrl.substring(STORED_PREFIX.length());
        if (filename.isBlank() || filename.contains("/") || filename.contains("\\") || filename.contains("..")) {
            throw new IllegalArgumentException("Avatar file was not found");
        }

        Path resolved = avatarDirectory.resolve(filename).normalize();
        if (!resolved.startsWith(avatarDirectory)) {
            throw new IllegalArgumentException("Avatar file was not found");
        }
        return resolved;
    }

    private String resolveExtension(String originalFilename) {
        if (originalFilename == null) {
            return ".jpg";
        }
        int extensionIndex = originalFilename.lastIndexOf('.');
        if (extensionIndex < 0 || extensionIndex == originalFilename.length() - 1) {
            return ".jpg";
        }
        String extension = originalFilename.substring(extensionIndex).toLowerCase(Locale.ROOT);
        return switch (extension) {
            case ".jpg", ".jpeg", ".png", ".gif", ".webp" -> extension;
            default -> ".jpg";
        };
    }
}
