package com.gnx.telemedicine.service;

import com.gnx.telemedicine.model.UserModel;
import com.gnx.telemedicine.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

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.Base64;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
public class FileUploadService {

    private final UserRepository userRepository;

    @Value("${file.upload-dir:uploads/avatars}")
    private String uploadDir;

    @Transactional
    public String uploadAvatar(String userEmail, MultipartFile file) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("File is empty");
        }

        // Validate file type - check both content type and extension
        String contentType = file.getContentType();
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename != null && originalFilename.contains(".")
                ? originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase()
                : "";
        
        // Allowed image types
        String[] allowedExtensions = {".jpg", ".jpeg", ".png", ".gif", ".webp"};
        boolean isAllowedExtension = false;
        for (String allowedExt : allowedExtensions) {
            if (extension.equals(allowedExt)) {
                isAllowedExtension = true;
                break;
            }
        }
        
        if (!isAllowedExtension) {
            throw new IllegalArgumentException("Only image files are allowed (JPG, PNG, GIF, WEBP)");
        }
        
        if (contentType == null || !contentType.startsWith("image/")) {
            throw new IllegalArgumentException("Invalid file type. Only image files are allowed");
        }
        
        // Validate specific content types
        String[] allowedContentTypes = {
            "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp"
        };
        boolean isAllowedContentType = false;
        for (String allowedType : allowedContentTypes) {
            if (contentType.equalsIgnoreCase(allowedType)) {
                isAllowedContentType = true;
                break;
            }
        }
        
        if (!isAllowedContentType) {
            throw new IllegalArgumentException("Invalid image format. Allowed: JPG, PNG, GIF, WEBP");
        }

        // Validate file size (max 5MB)
        long maxSize = 5 * 1024 * 1024; // 5MB
        if (file.getSize() > maxSize) {
            throw new IllegalArgumentException("File size exceeds 5MB limit. Current size: " + 
                String.format("%.2f", file.getSize() / 1024.0 / 1024.0) + "MB");
        }
        
        // Validate minimum file size (must be > 0)
        if (file.getSize() == 0) {
            throw new IllegalArgumentException("File is empty");
        }

        UserModel user = userRepository.findByEmail(userEmail)
                .orElseThrow(() -> new RuntimeException("User not found"));

        // Create upload directory if it doesn't exist
        Path uploadPath = Paths.get(uploadDir);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // Generate unique filename (reuse extension from validation above)
        String filename = UUID.randomUUID().toString() + extension;

        // Save file
        Path filePath = uploadPath.resolve(filename);
        Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

        // Generate URL (relative path that frontend can access)
        String avatarUrl = "/api/v3/files/avatars/" + filename;

        // Update user's avatar URL
        user.setAvatarUrl(avatarUrl);
        userRepository.save(user);

        log.info("Avatar uploaded for user {}: {}", userEmail, avatarUrl);
        return avatarUrl;
    }

    @Transactional
    public String uploadAvatarBase64(String userEmail, String base64Image) throws IOException {
        if (base64Image == null || base64Image.isEmpty()) {
            throw new IllegalArgumentException("Base64 image is empty");
        }

        UserModel user = userRepository.findByEmail(userEmail)
                .orElseThrow(() -> new RuntimeException("User not found"));

        // Remove data URL prefix if present (e.g., "data:image/png;base64,")
        String base64Data = base64Image;
        if (base64Image.contains(",")) {
            base64Data = base64Image.substring(base64Image.indexOf(",") + 1);
        }

        // Decode base64
        byte[] imageBytes = Base64.getDecoder().decode(base64Data);

        // Validate file size (max 5MB)
        if (imageBytes.length > 5 * 1024 * 1024) {
            throw new IllegalArgumentException("Image size exceeds 5MB limit");
        }

        // Create upload directory if it doesn't exist
        Path uploadPath = Paths.get(uploadDir);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // Generate unique filename
        String filename = UUID.randomUUID().toString() + ".jpg";

        // Save file
        Path filePath = uploadPath.resolve(filename);
        Files.write(filePath, imageBytes);

        // Generate URL (relative path that frontend can access)
        String avatarUrl = "/api/v3/files/avatars/" + filename;

        // Update user's avatar URL
        user.setAvatarUrl(avatarUrl);
        userRepository.save(user);

        log.info("Avatar uploaded (base64) for user {}: {}", userEmail, avatarUrl);
        return avatarUrl;
    }

    public void deleteAvatar(String userEmail) {
        UserModel user = userRepository.findByEmail(userEmail)
                .orElseThrow(() -> new RuntimeException("User not found"));

        if (user.getAvatarUrl() != null && !user.getAvatarUrl().isEmpty()) {
            try {
                // Extract filename from URL
                String filename = user.getAvatarUrl().substring(user.getAvatarUrl().lastIndexOf("/") + 1);
                Path filePath = Paths.get(uploadDir).resolve(filename);
                
                if (Files.exists(filePath)) {
                    Files.delete(filePath);
                }
            } catch (IOException e) {
                log.error("Error deleting avatar file for user {}: {}", userEmail, e.getMessage());
            }

            user.setAvatarUrl(null);
            userRepository.save(user);
        }
    }
}

