//
// Copyright 2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//

import Compound
import SwiftUI

struct TimelineMediaPreviewRedactConfirmationView: View {
    @Environment(\.dismiss) private var dismiss
    
    let item: TimelineMediaPreviewItem.Media
    @ObservedObject var context: TimelineMediaPreviewViewModel.Context
    
    @State private var sheetHeight: CGFloat = .zero
    private let topPadding: CGFloat = 19
    
    var body: some View {
        ScrollView {
            VStack(spacing: 0) {
                header
                preview
                buttons
            }
            .readHeight($sheetHeight)
        }
        .scrollBounceBehavior(.basedOnSize)
        .padding(.top, topPadding) // For the drag indicator
        .presentationDetents([.height(sheetHeight + topPadding)])
        .presentationDragIndicator(.visible)
        .presentationBackground(.compound.bgCanvasDefault)
        .preferredColorScheme(.dark)
    }
    
    private var header: some View {
        VStack(spacing: 16) {
            BigIcon(icon: \.delete, style: .alertSolid)
            
            VStack(spacing: 8) {
                Text(L10n.screenMediaDetailsRedactConfirmationTitle)
                    .font(.compound.headingMDBold)
                    .foregroundStyle(.compound.textPrimary)
                    .multilineTextAlignment(.center)
                
                Text(L10n.screenMediaDetailsRedactConfirmationMessage)
                    .font(.compound.bodyMD)
                    .foregroundStyle(.compound.textSecondary)
                    .multilineTextAlignment(.center)
            }
        }
        .padding(.top, 24)
        .padding(.bottom, 32)
        .padding(.horizontal, 24)
    }
    
    @ViewBuilder
    private var preview: some View {
        HStack(spacing: 12) {
            if let mediaSource = item.thumbnailMediaSource {
                Color.clear
                    .scaledFrame(size: 40)
                    .background {
                        LoadableImage(mediaSource: mediaSource,
                                      mediaType: .generic,
                                      blurhash: item.blurhash,
                                      mediaProvider: context.mediaProvider) {
                            Color.compound.bgSubtleSecondary
                        }
                        .aspectRatio(contentMode: .fill)
                    }
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }
                
            VStack(alignment: .leading, spacing: 4) {
                Text(item.filename ?? "")
                    .font(.compound.bodyMD)
                    .foregroundStyle(.compound.textPrimary)
                    
                if let contentType = item.contentType {
                    Group {
                        if let fileSize = item.fileSize {
                            Text(contentType) + Text(" – ") + Text(UInt(fileSize).formatted(.byteCount(style: .file)))
                        } else {
                            Text(contentType)
                        }
                    }
                    .font(.compound.bodySM)
                    .foregroundStyle(.compound.textSecondary)
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(.horizontal, 24)
        .padding(.bottom, 40)
    }
    
    private var buttons: some View {
        VStack(spacing: 16) {
            Button(L10n.actionRemove, role: .destructive) {
                context.send(viewAction: .redactConfirmation(item: item))
            }
            .buttonStyle(.compound(.primary))
            
            Button {
                dismiss()
            } label: {
                Text(L10n.actionCancel)
                    .padding(.vertical, 14)
            }
            .buttonStyle(.compound(.plain))
        }
        .padding(.bottom, 16)
        .padding(.horizontal, 16)
    }
}

// MARK: - Previews

import UniformTypeIdentifiers

struct TimelineMediaPreviewRedactConfirmationView_Previews: PreviewProvider, TestablePreview {
    static let viewModel = makeViewModel(contentType: .jpeg)
    
    static var previews: some View {
        if case let .media(mediaItem) = viewModel.state.currentItem {
            TimelineMediaPreviewRedactConfirmationView(item: mediaItem, context: viewModel.context)
        }
    }
    
    static func makeViewModel(contentType: UTType? = nil) -> TimelineMediaPreviewViewModel {
        let item = ImageRoomTimelineItem(id: .randomEvent,
                                         timestamp: .mock,
                                         isOutgoing: false,
                                         isEditable: true,
                                         canBeRepliedTo: true,
                                         isThreaded: false,
                                         sender: .init(id: "@alice:matrix.org",
                                                       displayName: "Alice",
                                                       avatarURL: .mockMXCUserAvatar),
                                         content: .init(filename: "Amazing Image.jpeg",
                                                        imageInfo: .mockImage,
                                                        thumbnailInfo: .mockThumbnail,
                                                        contentType: contentType))
        
        let timelineController = MockTimelineController(timelineKind: .media(.mediaFilesScreen))
        timelineController.timelineItems = [item]
        return TimelineMediaPreviewViewModel(initialItem: item,
                                             timelineViewModel: TimelineViewModel.mock(timelineKind: timelineController.timelineKind,
                                                                                       timelineController: timelineController),
                                             mediaProvider: MediaProviderMock(configuration: .init()),
                                             photoLibraryManager: PhotoLibraryManagerMock(.init()),
                                             userIndicatorController: UserIndicatorControllerMock(),
                                             appMediator: AppMediatorMock())
    }
}
