//
//  ChatView.swift
//  forShip
//
//  Created by Mamoru Sugita on 2023/10/16.
//
import SwiftUI

struct ChatView: View {
    @EnvironmentObject private var selectedTabModel: SelectedTabModel
    @ObservedObject var message = SharingData.message
    @State var isShowMember: Bool = false
    @State var isNotification = Preferences.ChatNotification
    @State var isFocus: Bool = true
    @State private var loadedMediaCount: Int = 0
    @State private var totalMediaCount: Int = 0
    @State private var isMediaLoading: Bool = false
    @State private var isUploadingDialogPresented: Bool = false
    var contentWidth: CGFloat

    var body: some View {
        ZStack {
            if message.mode {
                LinearGradient(gradient: Gradient(colors: [.chatEmargencyColor1,  .chatEmargencyColor2]), startPoint: .top, endPoint: .bottom)
                    .ignoresSafeArea()
            }
            VStack(spacing: 0) {
                ChatTitleView(isShowMember: $isShowMember, isNotification: $isNotification)

                ZStack {
                    ScrollViewReader { proxy in
                        ScrollView(.vertical) {
                            VStack {
                                ForEach(message.messages, id: \.messageId) { msg in
                                    if msg.message != nil {
                                        if msg.from == Preferences.UserName {
                                            //MARK: - 自分のメッセージ
                                            MyChatContentView(message: msg, contentWidth: contentWidth, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
                                                .padding(.bottom, 24)
                                        }else{
                                            //MARK: - 他人のメッセージ
                                            OtherChatContentView(message: msg, contentWidth: contentWidth, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
                                                .padding(.bottom, 24)
                                        }
                                    } else {
                                        AlertChatMessage(message: msg, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
                                            .padding(.bottom, 24)
                                    }
                                }
                            }
                            .padding(.top)
                            .onAppear {
                                guard !message.messages.isEmpty,
                                      let id = message.messages.last?.messageId else { return }

                                totalMediaCount = message.messages.reduce(0) { count, msg in
                                    count + (msg.type >= 0 ? 1 : 0)
                                }
                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                                    proxy.scrollTo(id, anchor: .bottom)
                                }
                            }
                            .onChange(of: message.messages.count) { newValue in
                                print(debug: "ChatView: onChange { newValue: \(newValue)")
                                withAnimation {
                                    if let id = message.messages.last?.messageId {
                                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                                            proxy.scrollTo(id, anchor: .bottom)
                                            
                                            //MARK: - Warningモードは既読は返さない
                                            if message.messages.last?.message != nil {
                                                if message.messages.last?.from != Preferences.UserName {
                                                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                                                        let getMessage = GetMessage()
                                                        getMessage.readNotification()
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            .onReceive(message.$messages) { (value) in
                                withAnimation {
                                    guard !value.isEmpty else {return}
                                    if let id = message.messages.last?.messageId {
                                        proxy.scrollTo(id, anchor: .bottom)
                                    }
                                }
                            }
                            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardDidShowNotification)) { _ in
                                Task {
                                    try await Task.sleep(for: .seconds(0.1))
                                    withAnimation {
                                        if let id = message.messages.last?.messageId {
                                            proxy.scrollTo(id, anchor: .bottom)
                                        }
                                    }
                                }
                            }
                        }
                    }
                    HStack {
                        Spacer()
                        VStack{
                            Button{
                                selectedTabModel.isShowChangeEmrMode.toggle()
                                isFocus = false
                            }label: {
                                Image(systemName: "exclamationmark.triangle.fill")
                                    .foregroundColor(.white)
                                    .frame(width: 48, height: 48)
                                    .background(ColorSet.Notice.color)
                                    .cornerRadius(50)
                            }.padding(9)
                            Spacer()
                        }
                    }
                    if isShowMember{
                        ChatMemberView()
                    }
                }
                .onTapGesture {
                    isFocus = false
                }
                .onAppear {
                    //MARK: - 画面が表示された時に実行 既読処理
                    if message.viewCnt > 0 {
                        message.viewCnt = 0
                    }
                }
                ChatInputView(isFocus: $isFocus, isUploadingDialogPresented: $isUploadingDialogPresented)
            }

            if !isMediaLoading {
                LoadingView()
            }

            if isUploadingDialogPresented {
//                UpLoadingView()
            }
        }
        .background(ColorSet.BackgroundPrimary.color)
    }

    //MARK: - 動画・画像読み込み完了後に最新チャットに移動
    private func handleMediaLoaded(proxy: ScrollViewProxy) {
        guard !message.messages.isEmpty,
              let id = message.messages.last?.messageId else { return }

        loadedMediaCount += 1
        if loadedMediaCount >= totalMediaCount {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                proxy.scrollTo(id, anchor: .bottom)
                isMediaLoading = true
            }
        }
    }
}

// MARK: - 全てのチャットのローディング画面
struct LoadingView: View {
    var body: some View {
        ZStack {
            Color.black.opacity(1.0)
                .edgesIgnoringSafeArea(.all)
            ProgressView("Loading...")
                .progressViewStyle(CircularProgressViewStyle(tint: .white))
                .foregroundColor(.white)
                .padding()
                .background(Color.gray.opacity(0.7))
                .cornerRadius(10)
        }
    }
}

// MARK: - 動画・画像のアップロード画面
struct UpLoadingView: View {
    var body: some View {
        ZStack {
            Color.black.opacity(0.8)
                .edgesIgnoringSafeArea(.all)
            ProgressView("UpLoading...")
                .progressViewStyle(CircularProgressViewStyle(tint: .white))
                .foregroundColor(.white)
                .padding()
                .background(Color.gray.opacity(0.7))
                .cornerRadius(10)
        }
    }
}

struct AlertChatMessage: View {
    @Environment(\.colorScheme) var colorScheme
    var message : ChatMessage
    var onMediaLoaded: (() -> Void)? = nil

    var body: some View {
        switch message.mode {
        case ChatMode.warningProgress.rawValue:
            HStack() {
                Rectangle()
                    .fill(ColorSet.ChatDate.color)
                    .frame(width: 20, height: 1)
                Text("Warning mode start  " + DateTextLib.ISO86012FormatText(message.time, format: "yyyy/MM/dd HH:mm", errFormat: ""))
                    .font(FontStyle.DateText.font)
                    .foregroundColor(ColorSet.ChatDate.color)
                Rectangle()
                    .fill(ColorSet.ChatDate.color)
                    .frame(width: 20, height: 1)
                    .onAppear {
                        onMediaLoaded?()
                    }
            }
        case ChatMode.normal.rawValue:
            HStack() {
                Rectangle()
                    .fill(ColorSet.ChatDate.color)
                    .frame(width: 20, height: 1)
                Text("Warning mode end  " + DateTextLib.ISO86012FormatText(message.time, format: "yyyy/MM/dd HH:mm", errFormat: ""))
                    .font(FontStyle.DateText.font)
                    .foregroundColor(ColorSet.ChatDate.color)
                Rectangle()
                    .fill(ColorSet.ChatDate.color)
                    .frame(width: 20, height: 1)
                    .onAppear {
                        onMediaLoaded?()
                    }
            }
        default:
            EmptyView()
                .onAppear {
                    onMediaLoaded?()
                }
        }
    }
}

#Preview {
    ChatView(contentWidth: CGFloat())
}

