//
//  MainTabView.swift
//  forShip
//
//  Created by Mamoru Sugita on 2023/10/13.
//

import SwiftUI

enum Tab: String, CaseIterable{
    case map = "tab_map"
    case chat = "tab_chat"
    case alert = "tab_notification"
    case menu = "tab_menu"

    var title: String{
        switch self {
        case .map: return "Map"
        case .chat: return "Chat"
        case .alert: return "Alert"
        case .menu: return "Menu"
        }
    }
}

struct MainTabView: View {
    @EnvironmentObject var selectedTabModel: SelectedTabModel
    @EnvironmentObject private var sceneDelegate: SceneDelegate
    @ObservedObject var location = SharingData.location
    @State var isSignout = false

    var isTabShow: Bool {
        sceneDelegate.tabWindow != nil
    }

    var isTaskSel: Bool {
        selectedTabModel.activeTab == .map
    }

    var body: some View {
        Group {
            if UIDevice.current.userInterfaceIdiom == .phone {
                phoneView
            } else {
                padView
            }
        }
        .onAppear {
            SharingData.location.focusOwnShip = true
            configureTabBarAppearance()
        }
    }

    private var phoneView: some View {
        ZStack(alignment: .bottom) {
            TabView(selection: $selectedTabModel.activeTab) {
                mapTab
                if SharingData.my.isCommunication {
                    ChatView().tag(Tab.chat)
                }
                NotificationView().tag(Tab.alert)
                MenuView(isSignout: $isSignout).tag(Tab.menu)
            }
            .sheet(isPresented: .constant(isTaskSel && isTabShow)) {
                MenuTaskView()
                    .zIndex(0)
                    .presentationDragIndicator(.hidden)
                    .presentationDetents([.height(150), .medium, .fraction(0.99)])
                    .presentationCornerRadius(15)
                    .presentationBackgroundInteraction(.enabled(upThrough: .medium))
                    .presentationBackground(ColorSet.BackgroundSecondary.color)
                    .interactiveDismissDisabled()
            }
        }
    }

    private var padView: some View {
        ZStack(alignment: .bottom) {
            TabView(selection: $selectedTabModel.activeTab) {
                mapTab.padding(.bottom, 50)
                if SharingData.my.isCommunication {
                    ChatView().padding(.bottom, 50).tag(Tab.chat)
                }
                NotificationView().padding(.bottom, 50).tag(Tab.alert)
                MenuView(isSignout: $isSignout).padding(.bottom, 50).tag(Tab.menu)
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }

    @ViewBuilder
    private var mapTab: some View {
        ZStack {
            MapRepresentable()
            MapInformation()
        }
        .ignoresSafeArea(edges: .top)
        .tag(Tab.map)
    }

    private func configureTabBarAppearance() {
        let appearance = UITabBarAppearance()
        appearance.backgroundColor = .clear
        UITabBar.appearance().scrollEdgeAppearance = appearance
        UITabBar.appearance().standardAppearance = appearance
    }
}

class MenuWindowManager {
    static let shared = MenuWindowManager()
    private var window: UIWindow?

    func showMenuView<Content: View>(_ content: Content, frame: CGRect) {
        guard window == nil else { return }

        let hostingController = UIHostingController(rootView: content)
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
            var rFrame = frame
            rFrame.size.height -= 20

            let newWindow = UIWindow(windowScene: windowScene)
            newWindow.rootViewController = hostingController
            newWindow.windowLevel = .alert + 1
            newWindow.backgroundColor = UIColor.clear
            newWindow.makeKeyAndVisible()
            newWindow.alpha = 0.8
            newWindow.frame = rFrame

            newWindow.layer.cornerRadius = 15
            newWindow.layer.masksToBounds = true

            self.window = newWindow
        }
    }

    func hideMenuView() {
        guard let window = window else { return }

        window.isHidden = true
        window.rootViewController = nil
        window.removeFromSuperview()
        self.window = nil
    }
}

struct NotificationBadge: View {
    let count: Int
    let font: Font
    var body: some View {
        Group {
            if count > 0 {
                Ellipse()
                    .fill(Color.red)
                    .frame(width: 12, height: 12)
                    .overlay(
                        Text(count < 10 ? "\(count)" : "-")
                            .font(font)
                            .foregroundColor(.white)
                    )
            }
        }
    }
}

struct CustomTabBar: View {
    @EnvironmentObject private var selectedTabModel: SelectedTabModel
    @State private var isModeAlert: Bool = false
    @State var isLocationAlert = false
    @Environment(\.openURL) var openURL
    @ObservedObject var my = SharingData.my
    @ObservedObject var message = SharingData.message
    @ObservedObject var location = SharingData.location
    @ObservedObject var pushHistory = SharingData.pushHistory
    @State var isSignalrRestert = false

    @State var isMenuTaskViewVisible = false

    var body: some View {
        VStack(spacing: 0){
            Divider()

            HStack(spacing: 0){
                ForEach(Tab.allCases, id: \.rawValue) { tab in
                    VStack{
                        ZStack(alignment: .bottomTrailing) {
                            if !SharingData.my.isCommunication && tab == Tab.chat {
                                Image("tab_chat_Invalid")
                                    .font(.title2)
                                    .onTapGesture {
                                        handleTabSelection(tab)
                                        print("Image for \(tab.rawValue) tapped")
                                    }
                            } else {
                                Image(selectedTabModel.activeTab == tab ? tab.rawValue + "_selected" : tab.rawValue)
                                    .font(.title2)
                                    .onTapGesture {
                                        handleTabSelection(tab)
                                        print("Image for \(tab.rawValue) tapped")
                                    }
                            }

                            //チャットTab上の既読マーク
                            if tab == Tab.chat {
                                NotificationBadge(count: message.viewCnt, font: FontStyle.VersionText.font)
                                    .id(message.viewCnt)
                            }


                            if tab == Tab.alert {
                                NotificationBadge(count: pushHistory.viewCnt, font: FontStyle.VersionText.font)
                                    .id(pushHistory.viewCnt)
                            }
                        }

                        Text(tab.title)
                            .font(.caption)
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .contentShape(Rectangle())
                }
            }
            .frame(height: 50)
        }
        .background(ColorSet.BottomNav.color)
        .modifier(ChangeModeAlertModifier(
            isPresented: $selectedTabModel.isShowChangeEmrMode,
            currentMode: message.mode,
            onConfirm: {
                var chatMode = message.mode
                chatMode.toggle()
                let signalRService = SignalR()
                signalRService.chatMode(mode: chatMode, completion: responseChatMode)
                message.sendInf = true

                DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                    restartChatMode()
                }
            }))
        .modifier(LocationAlertModifier(isPresented: $selectedTabModel.isLocationAlert))
        .modifier(UpdateAlertModifier(isPresented: $my.isUpDate, appStoreURL: URL(string: HttpRequestType.AppStore.rawValue)!))
        .modifier(WarningModeAlertModifier(isPresented: $isModeAlert, isSignalrRestert: $isSignalrRestert,
            onConfirm: {
                let signalRService = SignalR()
                signalRService.startConnection()
                isSignalrRestert = false
            }))
    }

    /**
     * タブが選択されたときの処理
     */
    private func handleTabSelection(_ tab: Tab) {
        selectedTabModel.activeTab = tab

        if tab == .map {
            selectedTabModel.isPoppver.toggle()
            // iPhoneは船に移動、iPadはMenu表示
            if UIDevice.current.userInterfaceIdiom == .phone {
                location.focusOwnShip = true
            } else {
                if isMenuTaskViewVisible {
                    MenuWindowManager.shared.hideMenuView()
                } else {
                    mapFunctionsView()
                }
                isMenuTaskViewVisible.toggle()
            }
        } else if tab == .chat {
            let message = GetMessage()
            message.start()
            message.readNotification()
            message.checkUnreadMessages()

            selectedTabModel.isPoppver = false

            if UIDevice.current.userInterfaceIdiom == .pad  {
                MenuWindowManager.shared.hideMenuView()
                isMenuTaskViewVisible = false
            }
        } else {
            selectedTabModel.isPoppver = false

            if UIDevice.current.userInterfaceIdiom == .pad {
                MenuWindowManager.shared.hideMenuView()
                isMenuTaskViewVisible = false
            }
        }
    }

    private func mapFunctionsView() {
        let screenBounds = UIScreen.main.bounds
        let screenHeight = screenBounds.height

        let menuTaskViewWidth: CGFloat = 400
        let menuTaskViewOffset: CGFloat = 80
        let menuTaskViewX: CGFloat = 10

        // メニューの縦サイズを画面の高さに応じて計算
        let menuTaskViewHeight = max(200, screenHeight * 0.8)

        // メニューのY座標を計算（画面の下部に配置）
        let menuTaskViewY = screenHeight - menuTaskViewHeight - menuTaskViewOffset

        MenuWindowManager.shared.showMenuView(
            MenuTaskView()
                .frame(width: menuTaskViewWidth, height: menuTaskViewHeight)
                .background(ColorSet.BackgroundSecondary.color)
                .cornerRadius(15),
            frame: CGRect(x: menuTaskViewX, y: menuTaskViewY, width: menuTaskViewWidth, height: menuTaskViewHeight)
        )
    }

    /**
     * Warninngモードレスポンス
     */
    func responseChatMode(error: Error?) {
        print(debug: "responseChatMode")
        message.sendInf = false

        if let e = error {
            print(debug: "Error chat:\(e)")
            isModeAlert = true
        } else {
            message.changeMode()
        }
    }

    /**
     * モード変更レスポンスが無かった場合
     */
    func restartChatMode() {
        if message.sendInf {
            let signalRService = SignalR()
            signalRService.stopConnection()
            Thread.sleep(forTimeInterval: 1.0)

            self.isSignalrRestert = true
        }
    }
}

#Preview {
    MainTabView()
        .environmentObject(SelectedTabModel())
        .environmentObject(SceneDelegate())
}
