import React, { useState } from 'react';
import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
import ActionSheet, { SheetManager } from 'react-native-actions-sheet';
import { Colors } from 'src/theme';
import { API_HOST } from 'src/constants';
import { getFontSize } from 'src/utils';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ChatProps, WarningProps } from '../types';
import { useNavigation } from '@react-navigation/native';
import { NAVIGATION_PAGES } from 'src/types';
import { usePostReportConversationMutation } from '@api/chat';
import { useChatStore } from 'src/stores/chatStore';
import TrashIcon from 'assets/icons/travels-screens/trash-solid.svg';
import BanIcon from 'assets/icons/messages/ban.svg';
import BellSlashIcon from 'assets/icons/messages/bell-slash.svg';
import { AvatarWithInitials } from 'src/components';
import MegaphoneIcon from 'assets/icons/messages/megaphone.svg';
import ExitIcon from 'assets/icons/messages/exit.svg';
import GroupIcon from 'assets/icons/messages/group-chat.svg';
import { database } from 'src/watermelondb';
import { BlockedUser, Chat } from 'src/watermelondb/models';
import { Q } from '@nozbe/watermelondb';
import {
  addDirtyAction,
  syncChatsIncremental
} from 'src/watermelondb/features/chat/data/chat.sync';

async function findChatRecord(chatData: ChatProps | null): Promise<Chat | null> {
  if (!chatData) return null;
  const chatsCollection = database.get<Chat>('chats');

  if (chatData.uid) {
    const res = await chatsCollection.query(Q.where('chat_uid', chatData.uid)).fetch();
    return res[0] ?? null;
  }

  if (chatData.groupToken) {
    const res = await chatsCollection
      .query(Q.where('group_chat_token', chatData.groupToken))
      .fetch();
    return res[0] ?? null;
  }

  return null;
}

async function upsertBlockedUserFromChat(chatData: ChatProps) {
  if (!chatData.uid) return;

  const blockedCollection = database.get<BlockedUser>('blocked_users');
  const existing = await blockedCollection.query(Q.where('user_id', chatData.uid)).fetch();

  const [firstName, ...rest] = (chatData.name ?? '').split(' ');
  const lastName = rest.join(' ');

  await database.write(async () => {
    if (existing.length > 0) {
      await existing[0].update((r) => {
        r.firstName = firstName || r.firstName;
        r.lastName = lastName || r.lastName;
        r.avatar = chatData.avatar ?? r.avatar;
        r.removed = false;
      });
    } else {
      await blockedCollection.create((r) => {
        r.userId = chatData.uid!;
        r.firstName = firstName || '';
        r.lastName = lastName || '';
        r.avatar = chatData.avatar ?? null;
        r.removed = false;
      });
    }
  });
}

const MoreModal = () => {
  const insets = useSafeAreaInsets();
  const navigation = useNavigation();
  const { setIsWarningModalVisible } = useChatStore();

  const [chatData, setChatData] = useState<
    | (ChatProps & {
      token: string;
    })
    | null
  >(null);
  const [name, setName] = useState<string | null>(null);
  const { mutateAsync: reportUser } = usePostReportConversationMutation();

  const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState<WarningProps | null>(null);

  const handleSheetOpen = (
    payload:
      | (ChatProps & {
        token: string;
      })
      | null
  ) => {
    setChatData(payload);
    setName(
      payload?.userType === 'blocked'
        ? 'Account is blocked'
        : payload?.userType === 'not_exist'
          ? 'Account does not exist'
          : (payload?.name ?? null)
    );
  };

  const handleMute = async () => {
    if (!chatData) return;

    const newMuted = chatData.muted === 1 ? 0 : 1;

    const chatRec = await findChatRecord(chatData);
    if (chatRec) {
      await database.write(() =>
        chatRec.update((r) => {
          r.muted = newMuted;
          addDirtyAction(r, { type: 'mute', value: newMuted });
        })
      );
    }

    setChatData((prev) => (prev ? { ...prev, muted: newMuted } : prev));

    try {
      await syncChatsIncremental(chatData.token);
    } catch (e) {
      console.warn('mute sync failed (will retry later):', e);
    }
  };

  const handleBlock = async () => {
    if (!chatData) return;

    setShouldOpenWarningModal({
      visible: true,
      title: 'Block user',
      buttonTitle: 'Block',
      message: `Are you sure you want to block ${name}?\nThis user will be blocked and you will not be able to send or receive messages from him/her.`,
      action: async () => {
        const chatRec = await findChatRecord(chatData);
        if (chatRec) {
          await database.write(() =>
            chatRec.update((r) => {
              r.removed = true;
              addDirtyAction(r, { type: 'block' });
            })
          );
        }

        await upsertBlockedUserFromChat(chatData);

        try {
          await syncChatsIncremental(chatData.token);
        } catch (e) {
          console.warn('block sync failed:', e);
        }
      }
    });

    setTimeout(() => {
      SheetManager.hide('more-modal');
      setShouldOpenWarningModal(null);
    }, 300);
  };

  const handleReport = async () => {
    if (!chatData) return;

    setShouldOpenWarningModal({
      visible: true,
      title: `Report ${name}`,
      buttonTitle: 'Report',
      message: `Are you sure you want to report ${name}?\nIf you proceed, the chat history with ${name} will become visible to NomadMania admins for investigation.`,
      action: async () => {
        chatData.uid &&
          (await reportUser({
            token: chatData.token,
            reported_user_id: chatData.uid
          }));
      }
    });

    setTimeout(() => {
      SheetManager.hide('more-modal');
      setShouldOpenWarningModal(null);
    }, 300);
  };

  const handleDelete = async () => {
    if (!chatData) return;

    setShouldOpenWarningModal({
      visible: true,
      title: 'Delete conversation',
      message: `Are you sure you want to delete conversation with ${name}?\nThis conversation will be deleted for both sides.`,
      action: async () => {
        const chatRec = await findChatRecord(chatData);
        if (chatRec) {
          await database.write(() =>
            chatRec.update((r) => {
              r.removed = true;
              addDirtyAction(r, { type: 'delete' });
            })
          );
        }

        try {
          await syncChatsIncremental(chatData.token);
        } catch (e) {
          console.warn('delete sync failed:', e);
        }
      }
    });

    setTimeout(() => {
      SheetManager.hide('more-modal');
      setShouldOpenWarningModal(null);
    }, 300);
  };

  const handleLeaveGroup = async () => {
    if (!chatData) return;

    setShouldOpenWarningModal({
      visible: true,
      title: `Leave group ${name}`,
      buttonTitle: 'Leave',
      message: `Are you sure you want to leave ${name}?`,
      action: async () => {
        const chatRec = await findChatRecord(chatData);
        if (chatRec) {
          await database.write(() =>
            chatRec.update((r) => {
              r.removed = true;
              addDirtyAction(r, { type: 'leave_group' });
            })
          );
        }

        try {
          await syncChatsIncremental(chatData.token);
        } catch (e) {
          console.warn('leaveGroup sync failed:', e);
        }
      }
    });

    setTimeout(() => {
      SheetManager.hide('more-modal');
      setShouldOpenWarningModal(null);
    }, 300);
  };

  const handleDeleteGroup = async () => {
    if (!chatData) return;

    setShouldOpenWarningModal({
      visible: true,
      title: `Delete ${name}`,
      message: `Are you sure you want to delete this group chat?\nThis action will remove the chat from your history, but it won't affect other participants.`,
      action: async () => {
        const chatRec = await findChatRecord(chatData);
        if (chatRec) {
          await database.write(() =>
            chatRec.update((r) => {
              r.removed = true;
              addDirtyAction(r, { type: 'delete' });
            })
          );
        }

        try {
          await syncChatsIncremental(chatData.token);
        } catch (e) {
          console.warn('deleteGroup sync failed:', e);
        }
      }
    });

    setTimeout(() => {
      SheetManager.hide('more-modal');
      setShouldOpenWarningModal(null);
    }, 300);
  };

  return (
    <ActionSheet
      id="more-modal"
      gestureEnabled={true}
      onBeforeShow={(sheetRef) => {
        const payload = sheetRef || null;
        handleSheetOpen(payload);
      }}
      onClose={() => {
        if (shouldOpenWarningModal) {
          setIsWarningModalVisible(shouldOpenWarningModal);
        }
      }}
      containerStyle={styles.sheetContainer}
      defaultOverlayOpacity={0.5}
      indicatorStyle={{ backgroundColor: 'transparent' }}
      safeAreaInsets={{ top: insets.top, bottom: insets.bottom || 24, left: 0, right: 0 }}
    >
      {chatData && (
        <View style={[styles.container]}>
          <TouchableOpacity
            style={styles.header}
            onPress={() => {
              SheetManager.hide('more-modal');
              if (chatData?.uid) {
                navigation.navigate(
                  ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: chatData.uid }] as never)
                );
              }
            }}
            disabled={chatData?.userType !== 'normal'}
          >
            {chatData?.avatar && (chatData.userType === 'normal' || !chatData.userType) ? (
              <Image source={{ uri: API_HOST + chatData.avatar }} style={styles.avatar} />
            ) : chatData.uid && (chatData.userType === 'normal' || !chatData.userType) ? (
              <AvatarWithInitials
                text={
                  chatData.name
                    .split(/ (.+)/)
                    .map((n) => n[0])
                    .join('') ?? ''
                }
                flag={API_HOST + 'flag.png'}
                size={32}
                fontSize={12}
              />
            ) : chatData.userType === 'normal' || !chatData.userType ? (
              <GroupIcon fill={Colors.DARK_BLUE} width={32} height={32} />
            ) : (
              <BanIcon fill={Colors.RED} width={32} height={32} />
            )}
            <Text
              style={[styles.name, chatData?.userType !== 'normal' ? { color: Colors.RED } : {}]}
            >
              {name}
            </Text>
          </TouchableOpacity>

          {chatData?.userType === 'normal' && (
            <View style={styles.optionsContainer}>
              <TouchableOpacity style={styles.option} onPress={handleMute}>
                <Text style={styles.optionText}>{chatData.muted === 1 ? 'Unmute' : 'Mute'}</Text>
                <BellSlashIcon fill={Colors.DARK_BLUE} />
              </TouchableOpacity>
            </View>
          )}

          {!chatData.announcement ? (
            <View style={[styles.optionsContainer, { paddingVertical: 0, gap: 0 }]}>
              {chatData?.groupToken && (
                <TouchableOpacity
                  style={[styles.option, styles.dangerOption]}
                  onPress={handleLeaveGroup}
                >
                  <Text style={[styles.optionText, styles.dangerText]}>Leave group chat</Text>
                  <ExitIcon fill={Colors.RED} width={16} />
                </TouchableOpacity>
              )}

              {chatData?.userType === 'normal' && chatData?.uid && (
                <>
                  <TouchableOpacity
                    style={[styles.option, styles.dangerOption]}
                    onPress={handleReport}
                  >
                    <Text style={[styles.optionText, styles.dangerText]}>Report {name}</Text>
                    <MegaphoneIcon fill={Colors.RED} />
                  </TouchableOpacity>

                  <TouchableOpacity
                    style={[styles.option, styles.dangerOption]}
                    onPress={handleBlock}
                  >
                    <Text style={[styles.optionText, styles.dangerText]}>Block {name}</Text>
                    <BanIcon fill={Colors.RED} />
                  </TouchableOpacity>
                </>
              )}

              {chatData?.uid ? (
                <TouchableOpacity
                  style={[styles.option, styles.dangerOption]}
                  onPress={handleDelete}
                >
                  <Text style={[styles.optionText, styles.dangerText]}>Delete chat</Text>
                  <TrashIcon fill={Colors.RED} width={18} height={18} />
                </TouchableOpacity>
              ) : (
                <TouchableOpacity
                  style={[styles.option, styles.dangerOption]}
                  onPress={handleDeleteGroup}
                >
                  <Text style={[styles.optionText, styles.dangerText]}>Delete group chat</Text>
                  <TrashIcon fill={Colors.RED} width={18} height={18} />
                </TouchableOpacity>
              )}
            </View>
          ) : null}
        </View>
      )}
    </ActionSheet>
  );
};

const styles = StyleSheet.create({
  sheetContainer: {
    borderTopLeftRadius: 15,
    borderTopRightRadius: 15
  },
  container: {
    backgroundColor: 'white',
    paddingHorizontal: 16,
    paddingTop: 8,
    gap: 16
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderBottomColor: Colors.FILL_LIGHT,
    gap: 8
  },
  avatar: {
    width: 32,
    height: 32,
    borderRadius: 16,
    borderWidth: 1,
    borderColor: Colors.FILL_LIGHT
  },
  name: {
    fontSize: getFontSize(14),
    fontFamily: 'montserrat-700',
    color: Colors.DARK_BLUE
  },
  optionsContainer: {
    paddingVertical: 10,
    paddingHorizontal: 8,
    gap: 16,
    borderRadius: 8,
    backgroundColor: Colors.FILL_LIGHT
  },
  option: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between'
  },
  optionText: {
    fontSize: getFontSize(12),
    fontWeight: '600',
    color: Colors.DARK_BLUE
  },
  dangerOption: {
    paddingVertical: 10,
    borderBottomWidth: 1,
    borderBlockColor: Colors.WHITE
  },
  dangerText: {
    color: Colors.RED
  }
});

export default MoreModal;
