class ChatFragment : Fragment() {

    private lateinit var binding: FragmentChatBinding
    private lateinit var mAuth: FirebaseAuth
    private lateinit var mDbRef: DatabaseReference
    private lateinit var currentUserId: String
    private lateinit var currentUserEmail: String

    private lateinit var messageList: ArrayList<ChatDTO>

    private lateinit var contentUid: String
    private lateinit var uid: String
    private lateinit var title: String

    private lateinit var recieverName: String
    private lateinit var recieverUid: String
    private lateinit var senderRoom: String
    private lateinit var recieverRoom: String
    private lateinit var timestamp: String
    lateinit var chatRoom: String

/*
    private lateinit var notificationSender: NotificationSender
*/

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mAuth = FirebaseAuth.getInstance()
        currentUserId = mAuth.currentUser?.uid?: ""
        currentUserEmail = mAuth.currentUser?.email?: ""
        mDbRef = FirebaseDatabase.getInstance().reference
uid = mAuth.currentUser?.uid?: ""
        recieverName = mAuth.currentUser?.email?: ""

arguments?.let{
contentUid =it.getString("contentUid").toString()
            recieverUid =it.getString("uid").toString()
            title =it.getString("title").toString()

            var senderUid =it.getString("senderUid")
            if (senderUid == null) {
                senderUid = currentUserId
            }

            chatRoom =listOf(senderUid, recieverUid).sortedBy{ it }.joinToString(separator = "_")
}

val firebaseService = MyFirebaseMessagingService.getInstance()
        firebaseService.sendNotificationToUser(recieverUid,""  ,requireContext())

/*
         notificationSender = NotificationSender("<http://localhost:3000/>")
*/

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentChatBinding.inflate(layoutInflater)

        binding.chatTitleText.text= title

        messageList = ArrayList()
        val chatAdapter: ChatAdapter = ChatAdapter(requireContext(), messageList, currentUserId)
        binding.chatRecycler.layoutManager= LinearLayoutManager(requireContext())
        binding.chatRecycler.adapter= chatAdapter

        binding.chatSendBtn.setOnClickListener{
val message = binding.chatInputEdit.text.toString()
            val currentTime = System.currentTimeMillis()
            val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.KOREA)
            sdf.timeZone= TimeZone.getTimeZone("Asia/Seoul")
            val dateString = sdf.format(currentTime)
            val messageObject = ChatDTO(
                currentUserId,
                message,
                recieverUid,
                currentTime,
                dateString
            )
            val senderChatRef =
                mDbRef.child("Chat").child("chatRooms").child(chatRoom).child("messages").push()

            senderChatRef.setValue(messageObject).addOnSuccessListener{
mDbRef.child("Chat").child("chatRooms").child(chatRoom).child("users")
                    .child(currentUserId).setValue(true)
                mDbRef.child("Chat").child("chatRooms").child(chatRoom).child("users")
                    .child(recieverUid).setValue(true)

                // 알림을 보내는 대상을 변경합니다.
                val firebaseService = MyFirebaseMessagingService.getInstance()
                firebaseService.sendNotificationToUser(recieverUid, message, requireContext())

                // 상대방이 채팅을 확인한 경우에만 read 값을 변경합니다.
                if (currentUserId == recieverUid) {
                    val messageId = senderChatRef.key
messageId?.let{
val messageRef = mDbRef.child("Chat").child("chatRooms").child(chatRoom)
                            .child("messages").child(it)
                        messageRef.child("read").setValue(true)
}
}
}

binding.chatInputEdit.setText("")
            chatAdapter.notifyDataSetChanged()
            binding.chatRecycler.scrollToPosition(messageList.size - 1)
}

val messagesRef = mDbRef.child("Chat").child("chatRooms").child(chatRoom).child("messages")
        messagesRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                messageList.clear()

                for (postSnapshot in snapshot.children) {
                    val message = postSnapshot.getValue(ChatDTO::class.java)
                    messageList.add(message!!)

                    // 상대방이 채팅을 확인한 경우에만 read 값을 변경합니다.
                    if (currentUserId == message.receiverUid && !message.read) {
                        val messageId = postSnapshot.key
messageId?.let{
val messageRef = messagesRef.child(it)
                            messageRef.child("read").setValue(true)
}
}
                }

                chatAdapter.notifyDataSetChanged()
                binding.chatRecycler.scrollToPosition(messageList.size - 1)
            }

            override fun onCancelled(error: DatabaseError) {
            }
        })

        return binding.root
}
}

2.MyFirebaseMessagingService

class MyFirebaseMessagingService : FirebaseMessagingService() {

    private val TAG = "FirebaseService"

    companion object {
        private const val CHANNEL_ID = "my_channel"

        var firebaseToken: String? = null

        private var instance: MyFirebaseMessagingService? = null

        fun getInstance(): MyFirebaseMessagingService {
            if (instance == null) {
                instance = MyFirebaseMessagingService()
            }
            return instance!!
        }
    }

    override fun onNewToken(token: String) {
        Log.d(TAG, "new Token : $token")
        firebaseToken = token

        val pref = getSharedPreferences("token", Context.MODE_PRIVATE)
        val editor = pref.edit()
        editor.putString("token", token).apply()
        editor.commit()
        Log.i(TAG, "Successfully saved the token")
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        Log.d(TAG, "From: ${remoteMessage.from}")

        if (remoteMessage.data.isNotEmpty()) {
            val uid = remoteMessage.data["uid"] ?: return
            val message = remoteMessage.data["message"] ?: return
            val nickname = remoteMessage.data["nickname"] ?: return
            sendNotificationToUser(uid, message,applicationContext)
        } else {
            Log.e(TAG, "Data is empty. Failed to receive the message.")
        }
        super.onMessageReceived(remoteMessage)
    }

    fun sendNotificationToUser(reciverUid: String, message: String, context: Context) {
        val dbRef = FirebaseDatabase.getInstance().reference
val userRef = dbRef.child("user").child(reciverUid)/*.child("FCMToken")*/
        userRef.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                val userData = snapshot.valueas? Map<String, Any>
                val fcmToken = userData?.get("FCMToken") as? String
                val nickname = userData?.get("nickname") as? String
                if (fcmToken != null) {
                    val remoteMessage = RemoteMessage.Builder("my_sender_id")
                        .setMessageId("my_message_id")
                        .addData("uid", reciverUid)
                        .addData("message", message)
                        .addData("nickname", nickname)
                        .build()
                    sendNotification(remoteMessage, context)
                } else {
                    Log.e(TAG, "FCM Token not found for the user with UID: $reciverUid")
                }
            }

            override fun onCancelled(error: DatabaseError) {
                Log.e(TAG, "Failed to retrieve FCM Token")
            }
        })
    }

    private fun sendNotification(remoteMessage: RemoteMessage, context: Context) {
        val channelId = CHANNEL_ID
        val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val uid = remoteMessage.data["uid"]
        val message = remoteMessage.data["message"]
        val nickname = remoteMessage.data["nickname"]

        val notificationBuilder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(nickname)
            .setContentText(message)
            .setAutoCancel(true)
            .setSound(soundUri)

        val intent = Intent(context, ChatRoomFragment::class.java)
        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            intent,
            PendingIntent.FLAG_ONE_SHOTor PendingIntent.FLAG_IMMUTABLE,
            null
        )

        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        }
        notificationManager.notify(0, notificationBuilder.build())
    }

    fun getFirebaseToken() {
        FirebaseMessaging.getInstance().token.addOnSuccessListener{
Log.d(TAG, "token=$it")
}
}
}

/*
package com.example.animal.service

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_ONE_SHOT
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.media.RingtoneManager
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.example.animal.ChatRoomFragment
import com.example.animal.LoginActivity
import com.example.animal.R
import com.example.animal.`interface`.NotificationAPI
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import kotlin.random.Random

class MyFirebaseMessagingService : FirebaseMessagingService() {

    private val TAG = "FirebaseService"

    companion object {
        private const val CHANNEL_ID = "my_channel"

        var firebaseToken: String? = null

        private const val SERVER_KEY =
            "C://Users//mj//workspace//keys//animal-1ccca-firebase-adminsdk-add7s-e0ed63689a.json" // You need to replace with your actual server key
        private const val CONTENT_TYPE = "application/json"
        private val retrofit = Retrofit.Builder()
            .baseUrl("<https://fcm.googleapis.com/>") // FCM base URL
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        val api: NotificationAPI = retrofit.create(NotificationAPI::class.java)

        private var instance: MyFirebaseMessagingService? = null
        fun getInstance(): MyFirebaseMessagingService {
            if (instance == null) {
                instance = MyFirebaseMessagingService()
            }
            return instance!!
        }
    }

    override fun onNewToken(token: String) {
        Log.d(TAG, "new Token : $token")
        firebaseToken = token

        val pref = getSharedPreferences("token", Context.MODE_PRIVATE)
        val editor = pref.edit()
        editor.putString("token", token).apply()
        editor.commit()
        Log.i(TAG, "Successfully saved the token")
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
 */
/*       Log.d(TAG, "From: ${remoteMessage.from}")

        if (remoteMessage.data.isNotEmpty()) {
            val uid = remoteMessage.data["uid"] ?: return
            val message = remoteMessage.data["message"] ?: return
            val nickname = remoteMessage.data["nickname"] ?: return
            sendNotificationToUser(uid, message, applicationContext)
        } else {
            Log.e(TAG, "Data is empty. Failed to receive the message.")
        }*//*

        super.onMessageReceived(remoteMessage)

        val intent = Intent(this, LoginActivity::class.java)
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val notificationID = Random.nextInt()

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel(notificationManager)
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
        )
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(remoteMessage.data["nickname"])
            .setContentText(remoteMessage.data["message"])
            .setSmallIcon(R.mipmap.ic_launcher)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()

        notificationManager.notify(notificationID, notification)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(notificationManager: NotificationManager) {
        val channelName = "channelName"
        val channel = NotificationChannel(CHANNEL_ID, channelName, IMPORTANCE_HIGH).apply {
            description = "My channel description"
            enableLights(true)
            lightColor = Color.GREEN
        }
        notificationManager.createNotificationChannel(channel)
    }

    fun sendNotificationToUser(receiverUid: String, message: String, context: Context) {
        val dbRef = FirebaseDatabase.getInstance().reference
        val userRef = dbRef.child("user").child(receiverUid)
        userRef.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                val userData = snapshot.value as? Map<String, Any>
                val fcmToken = userData?.get("FCMToken") as? String
                val nickname = userData?.get("nickname") as? String
                if (fcmToken != null && nickname != null) {
                    val remoteMessage = RemoteMessage.Builder("my_sender_id")
                        .setMessageId("my_message_id")
                        .addData("uid", receiverUid)
                        .addData("message", message)
                        .addData("nickname", nickname)
                        .build()
                    sendNotification(remoteMessage, context, receiverUid)
                    Log.d("FCM", "UID : $receiverUid")
                    Log.d("FCM", "FCM Token : $fcmToken")
                } else {
                    Log.e(TAG, "FCM Token not found for the user with UID: $receiverUid")
                }
            }

            override fun onCancelled(error: DatabaseError) {
                Log.e(TAG, "Failed to retrieve FCM Token")
            }
        })
    }

    private fun sendNotification(
        remoteMessage: RemoteMessage,
        context: Context,
        receiverUid: String
    ) {
        val channelId = CHANNEL_ID
        val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val receiverUid = remoteMessage.data["receiverUid"]
        val message = remoteMessage.data["message"]
        val nickname = remoteMessage.data["nickname"]

        val notificationBuilder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(nickname)
            .setContentText(message)
            .setAutoCancel(true)
            .setSound(soundUri)

        val intent = Intent(context, ChatRoomFragment::class.java)
        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            intent,
            PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE,
            null
        )

        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        }
        notificationManager.notify(0, notificationBuilder.build())
    }

    fun getFirebaseToken() {
        FirebaseMessaging.getInstance().token.addOnSuccessListener {
            Log.d(TAG, "token=$it")
        }
    }
}
*/

class RetrofitInstance {
    companion object {
        private val retrofit bylazy{
// Create a new HttpLoggingInterceptor.
            val logging = HttpLoggingInterceptor().apply{
level = HttpLoggingInterceptor.Level.BODY
}

// Add the interceptor to OkHttpClient.
            val client = OkHttpClient.Builder()
                .addInterceptor(logging)
                .build()

            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)  // Add the custom OkHttpClient.
                .build()
}

val api bylazy{
retrofit.create(NotificationAPI::class.java)
}
}
}

data class PushNotification(
    val data:NotificationData,
    val to : String
)

data class NotificationData(
    val title : String,
    val nickname : String,
    val message: String
)

data class NotificationData(
    val title : String,
    val nickname : String,
    val message: String
)