//
//  AvatarImageView.swift
//  Mastodon
//
//  Created by MainasuK Cirno on 2021-7-21.
//

import UIKit
import FLAnimatedImage
import AlamofireImage

public class AvatarImageView: FLAnimatedImageView {
    public var imageViewSize: CGSize?
    public var configuration = Configuration(url: nil)
    public var cornerConfiguration = CornerConfiguration()
}

extension AvatarImageView {
    
    public func prepareForReuse() {
        cancelTask()
        af.cancelImageRequest()
    }

    override public func layoutSubviews() {
        super.layoutSubviews()
        
        setup(corner: cornerConfiguration.corner)
    }
    
    private func setup(corner: CornerConfiguration.Corner) {
        layer.masksToBounds = true
        switch corner {
        case .circle:
            layer.cornerCurve = .circular
            layer.cornerRadius = frame.width / 2
        case .fixed(let radius):
            layer.cornerCurve = .continuous
            layer.cornerRadius = radius
        case .scale(let ratio):
            let radius = CGFloat(Int(bounds.width) / ratio)  // even number from quoter of width
            layer.cornerCurve = .continuous
            layer.cornerRadius = radius
        }
    }
    
    private func setup(border: CornerConfiguration.Border?) {
        layer.borderColor = border?.color.cgColor
        layer.borderWidth = border?.width ?? .zero
    }
    
}

extension AvatarImageView {
    
    public static let placeholder = UIImage.placeholder(color: .systemFill)
    
    public struct Configuration {
        public let url: URL?
        public let placeholder: UIImage?
        
        public init(
            url: URL?,
            placeholder: UIImage = AvatarImageView.placeholder
        ) {
            self.url = url
            self.placeholder = placeholder
        }
        
        public init(
            image: UIImage
        ) {
            self.url = nil
            self.placeholder = image
        }
    }
    
    public func configure(configuration: Configuration) {
        prepareForReuse()
        
        self.configuration = configuration
        
        guard let url = configuration.url else {
            image = configuration.placeholder
            return
        }
        
        switch url.pathExtension.lowercased() {
        case "gif":
            setImage(
                url: configuration.url,
                placeholder: configuration.placeholder,
                scaleToSize: imageViewSize
            )
        default:
            let filter: ImageFilter? = {
                if let imageViewSize = self.imageViewSize {
                    return ScaledToSizeFilter(size: imageViewSize)
                }
                guard self.frame.size.width != 0,
                      self.frame.size.height != 0
                else { return nil }
                return ScaledToSizeFilter(size: self.frame.size)
            }()
            
            af.setImage(
                withURL: url,
                placeholderImage: configuration.placeholder,
                filter: filter
            )
        }
    }
    
}

extension AvatarImageView {
    public struct CornerConfiguration {
        public let corner: Corner
        public let border: Border?

        public init(
            corner: Corner = .circle,
            border: Border? = nil
        ) {
            self.corner = corner
            self.border = border
        }
        
        public enum Corner {
            case circle
            case fixed(radius: CGFloat)
            case scale(ratio: Int = 4)      //  width / ratio
        }
        
        public struct Border {
            public let color: UIColor
            public let width: CGFloat
        }
    }
    
    public func configure(cornerConfiguration: CornerConfiguration) {
        self.cornerConfiguration = cornerConfiguration
        setup(corner: cornerConfiguration.corner)
        setup(border: cornerConfiguration.border)
    }
}
