import { FC, useCallback, useEffect, useState } from 'react';
import { TouchableOpacity, View, Text, Image, Dimensions } from 'react-native';
import { Series, usePostGetProfileRegions } 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 CompassIcon from 'assets/icons/travels-section/compass.svg';
import FriendsIcon from 'assets/icons/user-group.svg';
import FlagsIcon from 'assets/icons/travels-section/flags.svg';
import PhotosIcon from 'assets/icons/travels-section/images.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 { 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';

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;
  };
  updates: {
    countries: number;
    dare: number;
    friends: number;
    new_nm: number;
    photos: number;
    series: number;
    visited_regions: number;
    whs: number;
  };
  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 [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 [friendStatus, setFriendStatus] = useState<number | null>(null);
  const [modalInfo, setModalInfo] = useState({
    type: 'friend',
    message: '',
    isVisible: false,
    action: () => {},
    title: ''
  });

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

  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 = () => {
    return (
      (updates.countries && updates.countries > 0) ||
      (updates.visited_regions && updates.visited_regions > 0) ||
      (updates.dare && updates.dare > 0) ||
      (updates.series && updates.series > 0) ||
      (updates.whs && updates.whs > 0) ||
      (updates.new_nm && updates.new_nm > 0) ||
      (updates.photos && updates.photos > 0) ||
      (updates.friends && updates.friends > 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);
          }
        }
      );
    },
    [updateFriendStatus, token, data.friendDbId]
  );

  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 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>

        {isPublicView && token ? (
          <FriendStatus
            status={friendStatus}
            data={data}
            setModalInfo={setModalInfo}
            handleSendFriendRequest={handleSendFriendRequest}
            handleUpdateFriendStatus={handleUpdateFriendStatus}
          />
        ) : null}

        {data.friends.length > 0 ? (
          <InfoItem inline={true} title={'FRIENDS'}>
            <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[0] ?? ''}${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}

        {hasUpdates() ? (
          <InfoItem title={'UPDATES (last 90 days)'}>
            <View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
              {updates.countries && updates.countries > 0 ? (
                <View style={styles.updates}>
                  <FlagsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.countries}</Text>
                    <Text style={styles.updatesText}>visited countries</Text>
                  </View>
                </View>
              ) : null}
              {updates.visited_regions && updates.visited_regions > 0 ? (
                <View style={styles.updates}>
                  <RegionsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.visited_regions}</Text>
                    <Text style={styles.updatesText}>visited regions</Text>
                  </View>
                </View>
              ) : null}
              {updates.dare && updates.dare > 0 ? (
                <View style={styles.updates}>
                  <CompassIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.dare}</Text>
                    <Text style={styles.updatesText}>new DARE places</Text>
                  </View>
                </View>
              ) : null}
              {updates.series && updates.series > 0 ? (
                <View style={styles.updates}>
                  <SeriesIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.series}</Text>
                    <Text style={styles.updatesText}>new series</Text>
                  </View>
                </View>
              ) : null}
              {updates.whs && updates.whs > 0 ? (
                <View style={styles.updates}>
                  <WHSIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.whs}</Text>
                    <Text style={styles.updatesText}>new WHS sites</Text>
                  </View>
                </View>
              ) : null}
              {updates.new_nm && updates.new_nm > 0 ? (
                <View style={styles.updates}>
                  <RegionsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.new_nm}</Text>
                    <Text style={styles.updatesText}>new NM regions</Text>
                  </View>
                </View>
              ) : null}
              {updates.photos && updates.photos > 0 ? (
                <View style={styles.updates}>
                  <PhotosIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.photos}</Text>
                    <Text style={styles.updatesText}>new photos</Text>
                  </View>
                </View>
              ) : null}
              {updates.friends && updates.friends > 0 ? (
                <View style={styles.updates}>
                  <FriendsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                  <View>
                    <Text style={styles.updatesTextCount}>+{updates.friends}</Text>
                    <Text style={styles.updatesText}>new friends</Text>
                  </View>
                </View>
              ) : 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) => (
              <Tooltip
                isVisible={toolTipVisible === index}
                content={<Text style={{}}>{data.name}</Text>}
                contentStyle={{ backgroundColor: Colors.FILL_LIGHT }}
                placement="top"
                onClose={() => setToolTipVisible(null)}
                key={index}
                backgroundColor="transparent"
                allowChildInteraction={false}
              >
                <TouchableOpacity style={styles.series} onPress={() => setToolTipVisible(index)}>
                  <Image
                    source={{ uri: API_HOST + data.app_icon }}
                    style={{ width: 28, height: 28 }}
                  />
                  <Text style={[styles.headerText, { flex: 0 }]}>{data.score}</Text>
                </TouchableOpacity>
              </Tooltip>
            ))}
          </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'}>
            <Text style={[styles.titleText, { flex: 0 }]}>{data.bio}</Text>
          </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>

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