//
//  DropDownView.swift
//  AcaMate
//
//  Created by TAnine on 3/25/25.
//

import SwiftUI

class DropdownManager: ObservableObject {
    @Published var isPresented = false
    @Published var items: [String] = []
    @Published var anchor: CGRect = .zero
    @Published var font: Font = .body
    
    var onSelect: ((Int) -> Void)?
    
    func show(items: [String], anchor: CGRect,
              onSelect: @escaping (Int) -> Void) {
        self.items = items
        self.anchor = anchor
        self.onSelect = onSelect
        isPresented = true
    }
    
    func dismiss() {
        isPresented = false
    }
}

/// .coordinateSpace(name: "dropdownArea") 이거 지정을 해야 함
/// GlobalDropdownOverlay(manager: dropdownManager) 이거도 ZStack으로 넣어야 함
struct DropdownButton: View {
    @ObservedObject var manager: DropdownManager
    @State var title: String
    
    var onSelect: ((Int) -> Void)?
    let items: [String]
    
    
    init(manager: DropdownManager, title: String, items: [String],
         onSelect: @escaping (Int) -> Void) {
        self.manager = manager
        self.title = title
        self.items = items
        self.onSelect = onSelect
    }
    
    @State private var frame: CGRect = .zero
    
    var body: some View {
        Button {
            endTextEditing()
            manager.show(items: items, anchor: frame) { index in
                self.onSelect?(index)
                print("선택한 항목: \(items[index])")
                title = items[index]
            }
        } label: {
            HStack(alignment: .center) {
                Spacer()
                Text(title)
                    .font(manager.font)
                    .lineLimit(1)
                    .minimumScaleFactor(0.5)
                Image(systemName: /*manager.isPresented ? "chevron.up" : */ "chevron.down")
                    .resizable()
                    .frame(width: 8, height: 4)
                Spacer()
            }
            .padding(4)
            .background{
                RoundedRectangle(cornerRadius: 8)
                    .fill(Color.clear)
            }
        }
        .buttonStyle(.plain)
        .background(
            GeometryReader { geo in
                Color.clear
                    .onAppear {
                        frame = geo.frame(in: .named("dropdownArea"))
                    }
            }
        )
    }
}


struct GlobalDropdownOverlay: View {
    @ObservedObject var manager: DropdownManager
    
    @State private var scrollOffset: CGPoint = .zero
    
    private var maxVisibleItemCount: Int {
        if manager.items.count > 5 {
            return 5
        } else { return manager.items.count }
    }
    private let itemHeight: CGFloat = 42
    
    private var heightForDropBox: CGFloat {
        CGFloat(maxVisibleItemCount) * itemHeight
    }
    
    
    var body: some View {
        if manager.isPresented {
            ZStack(alignment: .topLeading) {
                Color.black.opacity(0.1)
                    .ignoresSafeArea()
                    .onTapGesture {
                        manager.dismiss()
                    }
                
                VStack(spacing: 0) {
                    if manager.items.count > maxVisibleItemCount {
                        OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { _ in
                            dropdownContent()
                        }
                    } else {
                        dropdownContent()
                    }
                }
                .frame(width: manager.anchor.width, height: heightForDropBox)
                .background{
                    RoundedRectangle(cornerRadius: 8)
                        .fill(Color(.Normal.normal))
                        .stroke(Color(.Second.normal))
                        .strokeBorder(lineWidth: 2)
                }
                .position(x: manager.anchor.midX,
                          y: manager.anchor.maxY+heightForDropBox/2)
                .animation(.easeOut(duration: 0.25), value: manager.isPresented)
            }
        }
    }
    
    @ViewBuilder
    private func dropdownContent() -> some View {
        VStack(alignment: .leading, spacing: 0) {
            ForEach(Array(manager.items.enumerated()), id: \.offset) { index, item in
                Button {
                    manager.onSelect?(index)
                    manager.dismiss()
                } label: {
                    Text(item)
                        .font(manager.font)
                        .lineLimit(1)
                        .minimumScaleFactor(0.4)
                        .padding([.leading, .trailing], 8)
                        .frame(maxWidth: .infinity, minHeight: 40, maxHeight: 40,  alignment: .center)
                    .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
                
                if index < manager.items.count - 1 {
                    Rectangle()
                        .fill(Color(.Second.normal).opacity(0.3))
                        .frame(maxWidth: .infinity, maxHeight: 2)
                }
            }
        }
    }
}
