import SDWebImageSwiftUI
import SwiftUI

// MARK: - PopupButtonDirection

public enum PopupButtonDirection {
    case row
    case column
    case auto
}

// MARK: - PopupButtonType

public enum PopupButtonType {
    case text
    case button
}

extension View {
    func measureLineHeights(font: Font,
                            oneLine: Binding<CGFloat>,
                            twoLines: Binding<CGFloat>) -> some View {
        overlay(
            VStack(spacing: 0) {
                Text("A")
                    .font(font)
                    .lineLimit(1)
                    .fixedSize()
                    .background(
                        GeometryReader { g in
                            Color.clear.onAppear { oneLine.wrappedValue = g.size.height }
                        }
                    )
                    .hidden()

                Text("A\nA")
                    .font(font)
                    .lineLimit(2)
                    .fixedSize(horizontal: false, vertical: true)
                    .background(
                        GeometryReader { g in
                            Color.clear.onAppear { twoLines.wrappedValue = g.size.height }
                        }
                    )
                    .hidden()
            }
            .frame(width: 0, height: 0)
        )
    }
}

// MARK: - PopupDisplay

public struct PopupDisplay: View {
    // MARK: Lifecycle

    public init(isPresented: Binding<Bool>, title: String = "", description: String = "", url: String = "", buttonDirection: PopupButtonDirection = .column, buttonType: PopupButtonType = .button, actionButtonTitle: String = "", closeButtonTitle: String = "", onPressAction: @escaping () -> Void = {}, onPressCloseButton: @escaping () -> Void = {}, onClose: @escaping () -> Void = {}, errorCode: String = "", isShowCloseIcon: Bool = true) {
        self._isPresented = isPresented
        self.title = title
        self.description = description
        self.url = url
        self.buttonDirection = buttonDirection
        self.buttonType = buttonType
        self.onPressAction = onPressAction
        self.onPressCloseButton = onPressCloseButton
        self.onClose = onClose
        self.closeButtonTitle = closeButtonTitle
        self.actionButtonTitle = actionButtonTitle
        self.errorCode = errorCode
        self.isShowCloseIcon = isShowCloseIcon
    }

    // MARK: Public
    
    @State private var oneLineH: CGFloat = 0
    @State private var twoLineH: CGFloat = 0

    private var fallbackLH: CGFloat { UIFont.preferredFont(forTextStyle: .body).lineHeight }
    private var perLine: CGFloat { max(twoLineH - oneLineH, oneLineH > 0 ? oneLineH : fallbackLH) }

    private func heightForLines(lines: CGFloat) -> CGFloat {
        guard oneLineH > 0 && twoLineH > 0 else { return ceil(fallbackLH * lines) }
        return ceil(oneLineH + max(0, lines - 1) * (twoLineH - oneLineH))
    }
    private var maxHeight8_5: CGFloat { heightForLines(lines: 8.5) }


    @State private var textHeight: CGFloat = .zero
    @State private var isScrollable = false
    
    public var body: some View {
        let language = UserDefaults.standard.string(forKey: "language")?.replacingOccurrences(of: "\"", with: "") ?? "vi"
        let errorCodeLabels: [String: String] = ["vi": "Mã lỗi: ", "en": "Error code: "]
        
        var shouldUseColumn: Bool {
            buttonDirection == .column || (buttonDirection == .auto && (closeButtonTitle.count > 12 || actionButtonTitle.count > 12))
        }

        VStack(spacing: 12) {
            ZStack(alignment: .topTrailing) {
                if(isShowCloseIcon) {
                    SwiftUI.Button(action: onClose) {
                        Image(systemName: "xmark.circle.fill")
                            .resizable()
                            .frame(width: 22, height: 22)
                            .overlay(RoundedRectangle(cornerRadius: Radius.L).stroke(Colors.black01, lineWidth: 2))
                    }.foregroundColor(Colors.black20)
                        .background(Colors.black01.cornerRadius(15))
                        .padding(.trailing, -11)
                        .padding(.top, -11)
                        .zIndex(1)
                        .accessibility(identifier: "ic_popup_close")
                }
                
                VStack(spacing: 0) {
                    if(!url.isEmpty) {
                        WebImage(url: URL(string: url), isAnimating: .constant(true))
                            .resizable()
                            .placeholder {
                                Rectangle()
                                    .fill(Color.gray.opacity(0.3))
                                    .aspectRatio(1.777, contentMode: .fit)
                                    .frame(maxWidth: .infinity, maxHeight: 184)
                            }
                            .aspectRatio(1.777, contentMode: .fit)
                            .frame(maxWidth: .infinity, alignment: .center)
                            .clipShape(RoundedCorner(radius: 15, corners: [.topLeft, .topRight]))
                            .clipped()
                    }
                    VStack(alignment: .leading, spacing: 0) {
                        MomoText(title, typography: .headerDefaultBold)
                            .padding(.top, 24)
                            .padding(.bottom, 8)
                            .lineLimit(2)
                            .accessibility(identifier: "title_popup_permission")
                        
                        Group {
                            if isScrollable {
                                ScrollView(showsIndicators: false) {
                                    MomoText(description, typography: .bodyDefaultRegular)
                                        .multilineTextAlignment(.leading)
                                        .background(GeometryReader { geo in
                                            Color.clear.onAppear { textHeight = geo.size.height }
                                        })
                                        .measureLineHeights(font: .body_default_regular,
                                                            oneLine: $oneLineH,
                                                            twoLines: $twoLineH)
                                        .accessibility(identifier: "description_popup_permission")
                                }
                                // Cap the visible height to ~8.5 lines
                                .frame(height: min(maxHeight8_5, textHeight))
                            } else {
                                MomoText(description, typography: .bodyDefaultRegular)
                                    .multilineTextAlignment(.leading)
                                    .background(GeometryReader { geo in
                                        Color.clear.onAppear {
                                            textHeight = geo.size.height
                                            // Trigger scroll at ~8.5 lines
                                            isScrollable = textHeight > maxHeight8_5
                                        }
                                    })
                                    .measureLineHeights(font: .body_default_regular,
                                                        oneLine: $oneLineH,
                                                        twoLines: $twoLineH)
                                    .accessibility(identifier: "description_popup_permission")
                            }
                        }
                        .padding(.bottom, 8)
                        
                        if(!errorCode.isEmpty) {
                            MomoText((errorCodeLabels[language] ?? "Mã lỗi: ") + errorCode, typography: .descriptionXsRegular, color: Colors.black12)
                                .lineLimit(1)
                                .padding(.bottom, 8)
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.horizontal, 24)
                    .padding(.bottom, 16)
                    
                    if shouldUseColumn {
                        if buttonType == .text {
                            ColumnTextButtons
                        } else {
                            ColumnButtons
                        }
                    } else {
                        if buttonType == .text {
                            RowTextButtons
                        } else {
                            RowButtons
                        }
                    }
                }
                .fixedSize(horizontal: false, vertical: true)
            }
        }
            .background(Color.white.cornerRadius(15))
            .padding(.horizontal, 12)
            .accessibilityElement(children: .ignore)
            .accessibility(identifier: "popup_notify")
    }

    // MARK: Internal

    @Binding var isPresented: Bool
    var title: String
    var description: String
    var url: String
    var buttonDirection: PopupButtonDirection
    var buttonType: PopupButtonType
    var onPressAction: () -> Void
    var onPressCloseButton: () -> Void
    var onClose: () -> Void
    var actionButtonTitle: String
    var closeButtonTitle: String
    var errorCode: String
    var isShowCloseIcon: Bool

    var RowTextButtons: some View {
        HStack {
            SwiftUI.Button(action: onPressCloseButton) {
                Text(closeButtonTitle)
                    .font(.action2)
            }.foregroundColor(Colors.black09)
                .padding(.trailing, 12)

            SwiftUI.Button(action: onPressAction) {
                Text(actionButtonTitle)
                    .font(.action2)
            }.foregroundColor(Colors.primary)
        }
        .frame(maxWidth: .infinity, alignment: .trailing)
        .padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 24))
    }

    var ColumnTextButtons: some View {
        VStack(alignment: .trailing) {
            SwiftUI.Button(action: onPressAction) {
                Text(actionButtonTitle)
                    .font(.action2)
            }.foregroundColor(Colors.primary)
                .padding(.bottom, 6)

            SwiftUI.Button(action: onPressCloseButton) {
                Text(closeButtonTitle)
                    .font(.action2)
            }.foregroundColor(Colors.black09)
        }
        .frame(maxWidth: .infinity, alignment: .trailing)
        .padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 24))
    }

    var RowButtons: some View {
        HStack {
            if(!closeButtonTitle.isEmpty) {
                Button(title: closeButtonTitle, action: onPressCloseButton, type: .text, size: .medium).accessibility(identifier: "btn_popup_cancel")
            }
            Button(title: actionButtonTitle, action: onPressAction, size: .medium)
                .accessibility(identifier: "btn_popup_allow")
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .padding(.horizontal, 24)
        .padding(.bottom, 24)
    }

    var ColumnButtons: some View {
        VStack(alignment: .trailing) {
            Button(
                title: actionButtonTitle,
                action: onPressAction,
                size: .medium
            ).accessibility(identifier: "btn_popup_allow")
            if(!closeButtonTitle.isEmpty) {
                Button(title: closeButtonTitle, action: onPressCloseButton, type: .text, size: .medium).accessibility(identifier: "btn_popup_cancel")
            }
        }
        .frame(maxWidth: .infinity, alignment: .trailing)
        .padding(.horizontal, 24)
        .padding(.bottom, 24)
    }

}
