import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { TouchableOpacity, View, Text, Image, Dimensions, useWindowDimensions } from 'react-native';
import {
  Series,
  usePostAuthenticateMutation,
  usePostGetProfileRegions,
  usePostGetUpdateQuery
} from '@api/user';
import { NavigationProp } from '@react-navigation/native';
import Modal from 'react-native-modal';
import Tooltip from 'react-native-walkthrough-tooltip';
import RegionsRenderer from '../RegionsRenderer';
import moment from 'moment';
import RenderHtml from 'react-native-render-html';

import CompassIcon from 'assets/icons/travels-section/compass.svg';
import FlagsIcon from 'assets/icons/travels-section/flags.svg';
import RegionsIcon from 'assets/icons/travels-section/regions.svg';
import SeriesIcon from 'assets/icons/travels-section/series.svg';
import WHSIcon from 'assets/icons/travels-section/whs.svg';
import ArrowIcon from 'assets/icons/next.svg';
import UNPIcon from 'assets/icons/travels-section/unp.svg';
import AuthIcon from 'assets/icons/authenticate-user.svg';
import SendIcon from 'assets/icons/messages/send.svg';

import { styles } from './styles';
import { InfoItem } from './InfoItem';
import { Colors } from 'src/theme';
import { API_HOST } from 'src/constants';
import { NAVIGATION_PAGES } from 'src/types';
import { AvatarWithInitials, WarningModal } from 'src/components';
import { usePostFriendRequestMutation, usePostUpdateFriendStatusMutation } from '@api/friends';
import FriendStatus from './FriendStatus';
import UpdatesRenderer from '../UpdatesRenderer';
import { useFriendsNotificationsStore } from 'src/stores/friendsNotificationsStore';
import { SheetManager } from 'react-native-actions-sheet';
import SeriesModal from './SeriesModal';
import { useSubscription } from 'src/screens/OfflineMapsScreen/useSubscription';

type PersonalInfoProps = {
  data: {
    bio: string;
    scores: { [key: string]: number | string };
    homebase: string;
    series: Series[];
    friends: {
      avatar: string | null;
      user_id: number;
      first_name: string;
      last_name: string;
      flag: string;
    }[];
    firstName: string;
    lastName: string;
    friendRequestSent: 0 | 1;
    friendRequestReceived: 0 | 1;
    isFriend: 0 | 1;
    friendDbId: number;
    ownProfile: 0 | 1;
    locationSharing: boolean;
    lastSeenRegion: string | null;
    lastSeenDate: string;
    lastSeenFlag: string | null;
    canBeAuthenticated: 0 | 1;
    setCanBeAuthenticated: (value: 0 | 1) => void;
    goToChat: () => void;
  };
  updates: {
    un_visited: number;
    un_new: number;
    unp_visited: number;
    unp_new: number;
    nm_visited: number;
    nm_new: number;
    new_dare: number;
    new_series: number;
    new_whs: number;
  } | null;
  userId: number;
  navigation: NavigationProp<any>;
  isPublicView: boolean;
  token: string | null;
};

const AVATAR_SIZE = 28;
const AVATAR_MARGIN = 8;
const SCREEN_PADDING_PERCENT = 0.05;

export const PersonalInfo: FC<PersonalInfoProps> = ({
  data,
  userId,
  updates,
  navigation,
  isPublicView,
  token
}) => {
  const { width: windowWidth } = useWindowDimensions();
  const contentWidth = windowWidth * 0.9;
  const htmlBaseStyle: any = useMemo(
    () => ({
      color: Colors.DARK_BLUE,
      fontWeight: '600',
      fontSize: 12
    }),
    []
  );

  const { isPremium } = useSubscription();

  const [showMoreSeries, setShowMoreSeries] = useState(false);
  const [type, setType] = useState<string>('nm');
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [toolTipVisible, setToolTipVisible] = useState<number | null>(null);
  const [tooltipUser, setTooltipUser] = useState<number | null>(null);
  const { mutateAsync: sendFriendRequest } = usePostFriendRequestMutation();
  const { mutateAsync: updateFriendStatus } = usePostUpdateFriendStatusMutation();
  const { mutateAsync: authenticateUser } = usePostAuthenticateMutation();
  const [friendStatus, setFriendStatus] = useState<number | null>(null);
  const [modalInfo, setModalInfo] = useState({
    type: 'friend',
    message: '',
    isVisible: false,
    action: () => {},
    title: ''
  });
  const [isUpdatesModalVisible, setIsUpdatesModalVisible] = useState(false);
  const [updateType, setUpdateType] = useState<string>('nm');

  const { data: regions } = usePostGetProfileRegions(token as string, userId, type);
  const { data: update } = usePostGetUpdateQuery(token as string, userId, updateType, true);

  const updateNotificationStatus = useFriendsNotificationsStore(
    (state) => state.updateNotificationStatus
  );

  useEffect(() => {
    if (data.isFriend === 1) {
      setFriendStatus(1);
    } else if (data.friendRequestReceived === 1) {
      setFriendStatus(2);
    } else if (data.friendRequestSent === 1) {
      setFriendStatus(3);
    } else {
      setFriendStatus(4);
    }
  }, [data]);

  const scores = [
    { name: 'score_nm', score: 'NM' },
    { name: 'score_un', score: 'UN' },
    { name: 'score_unp', score: 'UN+' },
    { name: 'score_mqp', score: 'DARE' },
    { name: 'score_tcc', score: 'TCC' },
    { name: 'score_deep', score: 'DEEP' },
    { name: 'score_slow', score: 'SLOW' },
    { name: 'score_yes', score: 'YES' },
    { name: 'score_kye', score: 'KYE' },
    { name: 'score_whs', score: 'WHS' }
  ];

  const handleOpenModal = (type: string) => {
    switch (type) {
      case 'NM':
        setType('nm');
        break;
      case 'DARE':
        setType('mqp');
        break;
      case 'UN':
        setType('un');
        break;
      case 'UN+':
        setType('unp');
        break;
      case 'TCC':
        setType('tcc');
        break;
      case 'SLOW':
        setType('slow');
        break;
      case 'YES':
        setType('yes');
        break;
      case 'WHS':
        setType('whs');
        break;
      case 'KYE':
        setType('kye');
      case 'DEEP':
        setType('deep');
    }
    setIsModalVisible(true);
  };

  const hasUpdates = () => {
    if (!updates) return false;

    return (
      (updates.un_visited && updates.un_visited > 0) ||
      (updates.unp_visited && updates.unp_visited > 0) ||
      (updates.nm_visited && updates.nm_visited > 0) ||
      (updates.new_dare && updates.new_dare > 0) ||
      (updates.new_series && updates.new_series > 0) ||
      (updates.new_whs && updates.new_whs > 0)
    );
  };

  const handleSendFriendRequest = useCallback(async () => {
    await sendFriendRequest(
      { token: token as string, uid: userId },
      {
        onSuccess: () => {
          setFriendStatus(3);
        }
      }
    );
  }, [sendFriendRequest, token, userId]);

  const handleUpdateFriendStatus = useCallback(
    async (status: number) => {
      await updateFriendStatus(
        { token: token as string, id: data.friendDbId, status },
        {
          onSuccess: () => {
            status === -1 || status === 2 ? setFriendStatus(4) : setFriendStatus(status);
          }
        }
      );
      updateNotificationStatus();
    },
    [updateFriendStatus, token, data.friendDbId]
  );

  const handleOpenUpdates = (type: string) => {
    setUpdateType(type);
    setIsUpdatesModalVisible(true);
  };

  const formatDateToLocalTime = (utcDate: string) => {
    const date = moment.utc(utcDate).local();
    const now = moment();

    if (now.diff(date, 'days') === 1) {
      return 'yesterday';
    }

    if (now.diff(date, 'weeks') === 1) {
      return 'last week';
    }

    return date.fromNow();
  };

  const handleAuthenticate = () => {
    authenticateUser(
      { token: token as string, profile_id: userId },
      {
        onSuccess: () => {
          data.setCanBeAuthenticated(0);
        }
      }
    );
  };

  const screenWidth = Dimensions.get('window').width;
  const availableWidth = screenWidth * (1 - 2 * SCREEN_PADDING_PERCENT);
  const maxAvatars = Math.floor(availableWidth / (AVATAR_SIZE - AVATAR_MARGIN)) - 2;

  return (
    <View>
      <View style={styles.wrapper}>
        <View style={styles.scoreContainer}>
          {scores.map((score, index) => {
            let scoreRank = +data.scores[score.name] > 0 ? data.scores[score.name] : '-';

            if (score.score === 'YES' && +scoreRank >= 4500) {
              scoreRank = '-';
            }

            return (
              <TouchableOpacity
                key={index}
                style={styles.rankingItem}
                disabled={score.score === 'DEEP' || score.score === 'KYE'}
                onPress={() => handleOpenModal(score.score)}
              >
                <Text style={styles.rankingScore}>{scoreRank}</Text>
                <Text style={[styles.titleText, { flex: 0 }]}>{score.score}</Text>
              </TouchableOpacity>
            );
          })}
        </View>

        {data.ownProfile === 0 && token ? (
          <View style={{ gap: 8 }}>
            <TouchableOpacity
              style={[styles.authBtn, { backgroundColor: Colors.ORANGE }]}
              onPress={data.goToChat}
            >
              <SendIcon fill={Colors.WHITE} height={15} />
              <Text style={[styles.authText, { color: Colors.WHITE }]}>Send message</Text>
            </TouchableOpacity>
            <View style={{ gap: 8, flexDirection: 'row', alignItems: 'flex-end' }}>
              <FriendStatus
                status={friendStatus}
                data={data}
                setModalInfo={setModalInfo}
                handleSendFriendRequest={handleSendFriendRequest}
                handleUpdateFriendStatus={handleUpdateFriendStatus}
                authButton={data.canBeAuthenticated}
              />
              {data.canBeAuthenticated ? (
                <TouchableOpacity
                  onPress={() =>
                    setModalInfo({
                      isVisible: true,
                      type: 'authenticate',
                      message: `Please confirm that you trust and have personally met ${data.firstName} ${data.lastName}.`,
                      action: handleAuthenticate,
                      title: ''
                    })
                  }
                  style={styles.authBtn}
                >
                  <AuthIcon />
                  <Text style={styles.authText}>Trust</Text>
                </TouchableOpacity>
              ) : null}
            </View>
          </View>
        ) : null}

        {data.friends.length > 0 ? (
          <InfoItem inline={true} title={`FRIENDS (${data.friends.length})`}>
            <View style={{ flexDirection: 'row', flex: 1 }}>
              {data.friends.slice(0, maxAvatars).map((friend, index) => (
                <Tooltip
                  isVisible={tooltipUser === index}
                  content={
                    <TouchableOpacity
                      onPress={() => {
                        setTooltipUser(null);
                        navigation.navigate(
                          ...([
                            NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW,
                            { userId: friend.user_id }
                          ] as never)
                        );
                      }}
                    >
                      <Text style={{}}>
                        {friend.first_name} {friend.last_name}
                      </Text>
                    </TouchableOpacity>
                  }
                  contentStyle={{ backgroundColor: Colors.FILL_LIGHT }}
                  placement="top"
                  onClose={() => setTooltipUser(null)}
                  key={index}
                  backgroundColor="transparent"
                >
                  <TouchableOpacity
                    onPress={() => setTooltipUser(index)}
                    style={{ marginLeft: index === 0 ? 0 : -AVATAR_MARGIN }}
                  >
                    {friend.avatar ? (
                      <Image
                        style={styles.avatar}
                        source={{ uri: API_HOST + '/img/avatars/' + friend.avatar }}
                      />
                    ) : (
                      <AvatarWithInitials
                        text={`${friend?.first_name ? friend.first_name[0] : ''}${friend?.last_name ? friend.last_name[0] : ''}`}
                        flag={API_HOST + '/img/flags_new/' + friend.flag}
                        size={28}
                        borderColor={Colors.DARK_LIGHT}
                        fontSize={11}
                        borderWidth={1}
                      />
                    )}
                  </TouchableOpacity>
                </Tooltip>
              ))}
            </View>

            <Tooltip
              isVisible={tooltipUser === -1}
              content={<Text style={{}}>Only friends can see details.</Text>}
              contentStyle={{ backgroundColor: Colors.FILL_LIGHT, justifyContent: 'flex-end' }}
              placement="top"
              onClose={() => setTooltipUser(null)}
              backgroundColor="transparent"
              allowChildInteraction={false}
            >
              <TouchableOpacity
                style={[styles.avatar, styles.userShowMore]}
                onPress={() => {
                  if (friendStatus !== 1 && isPublicView) {
                    setTooltipUser(-1);
                  } else {
                    data.ownProfile === 0
                      ? navigation.navigate(
                          ...([
                            NAVIGATION_PAGES.FRIENDS_LIST,
                            {
                              id: userId,
                              type: 'friends'
                            }
                          ] as never)
                        )
                      : navigation.navigate(NAVIGATION_PAGES.MY_FRIENDS);
                  }
                }}
              >
                <View style={styles.dots}></View>
                <View style={styles.dots}></View>
                <View style={styles.dots}></View>
              </TouchableOpacity>
            </Tooltip>
          </InfoItem>
        ) : null}

        {data.lastSeenRegion && data.lastSeenDate ? (
          <View style={{ gap: 10 }}>
            <View style={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}>
              <Text style={[styles.headerText, { flex: 0 }]}>LAST SEEN </Text>
              <Text style={[styles.titleText]}>{formatDateToLocalTime(data.lastSeenDate)}</Text>
            </View>
            <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
              <RegionsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
              <Text style={styles.titleText}>in {data.lastSeenRegion}</Text>
            </View>
          </View>
        ) : null}

        {updates && hasUpdates() ? (
          <InfoItem title={'VISITED IN THE LAST 90 DAYS'}>
            <View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
              {updates.nm_visited && updates.nm_visited > 0 ? (
                <TouchableOpacity style={styles.updates} onPress={() => handleOpenUpdates('nm')}>
                  <RegionsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  {updates.nm_new && updates.nm_new > 0 ? (
                    <View>
                      <Text style={styles.updatesText}>
                        {updates.nm_visited} (+{updates.nm_new} new)
                      </Text>
                      <Text style={styles.updatesText}>NM regions</Text>
                    </View>
                  ) : (
                    <Text style={styles.updatesText}>{updates.nm_visited} NM regions</Text>
                  )}
                </TouchableOpacity>
              ) : null}

              {updates.un_visited && updates.un_visited > 0 ? (
                <TouchableOpacity style={styles.updates} onPress={() => handleOpenUpdates('un')}>
                  <FlagsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  {updates.un_new && updates.un_new > 0 ? (
                    <View>
                      <Text style={styles.updatesText}>
                        {updates.un_visited} (+{updates.un_new} new)
                      </Text>
                      <Text style={styles.updatesText}>UN countries</Text>
                    </View>
                  ) : (
                    <Text style={styles.updatesText}>{updates.un_visited} UN countries</Text>
                  )}
                </TouchableOpacity>
              ) : null}

              {updates.unp_visited && updates.unp_visited > 0 ? (
                <TouchableOpacity style={styles.updates} onPress={() => handleOpenUpdates('unp')}>
                  <UNPIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  {updates.unp_new && updates.unp_new > 0 ? (
                    <View>
                      <Text style={styles.updatesText}>
                        {updates.unp_visited} (+{updates.unp_new} new)
                      </Text>
                      <Text style={styles.updatesText}>UN+ states</Text>
                    </View>
                  ) : (
                    <Text style={styles.updatesText}>{updates.unp_visited} UN+ states</Text>
                  )}
                </TouchableOpacity>
              ) : null}

              {updates.new_dare && updates.new_dare > 0 ? (
                <TouchableOpacity style={styles.updates} onPress={() => handleOpenUpdates('dare')}>
                  <CompassIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <Text style={styles.updatesText}>{updates.new_dare} new DAREs</Text>
                </TouchableOpacity>
              ) : null}

              {updates.new_series && updates.new_series > 0 ? (
                <TouchableOpacity
                  style={styles.updates}
                  onPress={() => handleOpenUpdates('series')}
                >
                  <SeriesIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <Text style={styles.updatesText}>{updates.new_series} new Series</Text>
                </TouchableOpacity>
              ) : null}

              {updates.new_whs && updates.new_whs > 0 ? (
                <TouchableOpacity style={styles.updates} onPress={() => handleOpenUpdates('whs')}>
                  <WHSIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <Text style={styles.updatesText}>{updates.new_whs} new WHS</Text>
                </TouchableOpacity>
              ) : null}
            </View>
          </InfoItem>
        ) : null}

        {data.series?.length > 0 && (
          <InfoItem showMore={showMoreSeries} inline={true} title={'SERIES'}>
            {data.series?.slice(0, showMoreSeries ? data.series.length : 8).map((data, index) => (
              <TouchableOpacity
                key={index}
                style={styles.series}
                onPress={() => {
                  if (isPremium) {
                    SheetManager.show('visited-series-modal', {
                      payload: {
                        userId,
                        seriesId: data.id
                      } as any
                    });
                  } else {
                    setModalInfo({
                      isVisible: true,
                      type: 'success',
                      action: () => {},
                      message:
                        'This feature is available to Premium users. Premium account settings can be managed on our website.',
                      title: 'Premium Feature'
                    });
                  }
                }}
              >
                <Image
                  source={{ uri: API_HOST + data.app_icon }}
                  style={{ width: 28, height: 28 }}
                />
                <Text style={[styles.headerText, { flex: 0 }]}>{data.score}</Text>
              </TouchableOpacity>
            ))}
          </InfoItem>
        )}

        {data.series?.length > 8 ? (
          <TouchableOpacity onPress={() => setShowMoreSeries(!showMoreSeries)}>
            <View
              style={[
                { alignItems: 'center' },
                showMoreSeries
                  ? { transform: 'rotate(180deg)', paddingTop: 8 }
                  : { paddingBottom: 8 }
              ]}
            >
              <ArrowIcon stroke={'#B7C6CB'} />
            </View>
          </TouchableOpacity>
        ) : null}

        <View style={{ display: 'flex', flexDirection: 'row' }}>
          <Text style={styles.headerText}>REGION OF ORIGIN</Text>
          <Text style={styles.titleText}>{data.homebase}</Text>
        </View>

        {data.bio && data.bio.length > 0 && (
          <InfoItem title={'BIO'}>
            <RenderHtml
              contentWidth={contentWidth}
              source={{ html: data.bio }}
              baseStyle={htmlBaseStyle}
            />
          </InfoItem>
        )}
      </View>

      <Modal
        isVisible={isModalVisible}
        onBackdropPress={() => setIsModalVisible(false)}
        onBackButtonPress={() => setIsModalVisible(false)}
        style={styles.modal}
        statusBarTranslucent={true}
        presentationStyle="overFullScreen"
      >
        <RegionsRenderer type={type} regions={regions} setIsModalVisible={setIsModalVisible} />
      </Modal>

      <Modal
        isVisible={isUpdatesModalVisible}
        onBackdropPress={() => setIsUpdatesModalVisible(false)}
        onBackButtonPress={() => setIsUpdatesModalVisible(false)}
        style={styles.modal}
        statusBarTranslucent={true}
        presentationStyle="overFullScreen"
      >
        <UpdatesRenderer
          type={updateType}
          updates={update ?? null}
          setIsModalVisible={setIsUpdatesModalVisible}
        />
      </Modal>

      <WarningModal
        type={modalInfo.type}
        isVisible={modalInfo.isVisible}
        message={modalInfo.message}
        action={modalInfo.action}
        onClose={() => setModalInfo({ ...modalInfo, isVisible: false, title: '' })}
        title={modalInfo.title}
      />

      <SeriesModal />
    </View>
  );
};
