import React, { FC, ReactNode, useState } from 'react';
import { Linking, ScrollView, Text, TouchableOpacity, View, Image } from 'react-native';
import { CommonActions, NavigationProp, useNavigation } from '@react-navigation/native';
import Modal from 'react-native-modal';
import Tooltip from 'react-native-walkthrough-tooltip';

import {
  type Score,
  type Series,
  type SocialData,
  usePostGetProfileInfoPublicQuery,
  usePostGetProfileInfoQuery,
  usePostGetProfileRegions
} from '@api/user';

import {
  BigText,
  Button,
  PageWrapper,
  Loading,
  AvatarWithInitials,
  Header
} from '../../../components';
import { Colors } from '../../../theme';
import { styles } from './styles';
import { ButtonVariants } from '../../../types/components';

import { API_HOST } from '../../../constants';
import { NAVIGATION_PAGES } from '../../../types';
import { storage, StoreType } from '../../../storage';
import { getFontSize, getYears } from '../../../utils';

import IconFacebook from '../../../../assets/icons/facebook.svg';
import IconInstagram from '../../../../assets/icons/instagram.svg';
import IconTwitter from '../../../../assets/icons/x(twitter).svg';
import IconYouTube from '../../../../assets/icons/youtube.svg';
import IconGlobe from '../../../../assets/icons/bottom-navigation/globe.svg';
import IconLink from '../../../../assets/icons/link.svg';
import GearIcon from '../../../../assets/icons/gear.svg';
import ArrowIcon from '../../../../assets/icons/next.svg';
import RegionsRenderer from './RegionsRenderer';

type Props = {
  navigation: NavigationProp<any>;
  route: any;
};

const ProfileScreen: FC<Props> = ({ navigation, route }) => {
  const isPublicView = route.name === NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW;

  const token = storage.get('token', StoreType.STRING) as string;
  const currentUserId = storage.get('uid', StoreType.STRING) as string;

  if (!token) return <UnauthenticatedProfileScreen />;

  const { data, isFetching } = isPublicView
    ? usePostGetProfileInfoPublicQuery(route.params?.userId, true)
    : usePostGetProfileInfoQuery(token, true);

  if (!data || isFetching) return <Loading />;

  const handleGoToMap = () => {
    isPublicView
      ? navigation.navigate(NAVIGATION_PAGES.USERS_MAP, { userId: route.params?.userId, data })
      : navigation.dispatch(
          CommonActions.reset({
            index: 1,
            routes: [{ name: NAVIGATION_PAGES.IN_APP_MAP_TAB }]
          })
        );
  };

  return (
    <PageWrapper>
      {isPublicView && <Header label="Profile" />}
      <TouchableOpacity
        style={[styles.usersMap, { backgroundColor: '#EBF2F5' }]}
        onPress={handleGoToMap}
      >
        <Image
          source={{
            uri: `${API_HOST}/img/single_maps/${isPublicView ? route.params?.userId : currentUserId}.png`
          }}
          style={styles.usersMap}
        />
      </TouchableOpacity>

      <View style={styles.pageWrapper}>
        <View style={{ top: -34 }}>
          {data.avatar ? (
            <Image style={styles.avatar} source={{ uri: API_HOST + data.avatar }} />
          ) : (
            <AvatarWithInitials
              text={`${data.first_name[0] ?? ''}${data.last_name[0] ?? ''}`}
              flag={API_HOST + data.homebase_flag}
              size={64}
              borderColor={Colors.WHITE}
            />
          )}
        </View>
        <View style={{ gap: 5, flex: 1 }}>
          <Text style={[styles.headerText, { fontSize: getFontSize(18), flex: 0 }]}>
            {data.first_name} {data.last_name}
          </Text>
          <View style={styles.userInfoContainer}>
            <View style={styles.userInfo}>
              <Text
                style={{ color: Colors.DARK_BLUE, fontWeight: '600', fontSize: getFontSize(12) }}
              >
                Age: {getYears(data.date_of_birth)}
              </Text>
              <Image source={{ uri: API_HOST + data.homebase_flag }} style={styles.countryFlag} />
              {data.homebase2_flag && data.homebase2_flag !== data.homebase_flag ? (
                <Image
                  source={{ uri: API_HOST + data.homebase2_flag }}
                  style={[styles.countryFlag, { marginLeft: -15 }]}
                />
              ) : null}
            </View>

            {!isPublicView ? (
              <TouchableOpacity
                style={styles.settings}
                onPress={() => navigation.navigate(NAVIGATION_PAGES.EDIT_PERSONAL_INFO)}
              >
                <GearIcon
                  width={20}
                  height={20}
                  fill={Colors.DARK_BLUE}
                  style={{ alignSelf: 'center' }}
                />
              </TouchableOpacity>
            ) : null}
          </View>
        </View>
      </View>

      <PersonalInfo
        data={{
          bio: data.bio,
          date_of_birth: data.date_of_birth,
          scores: data.scores,
          links: data.links,
          homebase: data.homebase_name,
          homebase2: data.homebase2_name,
          series: data.series
        }}
        userId={isPublicView ? route.params?.userId : +currentUserId}
      />
    </PageWrapper>
  );
};

type PersonalInfoProps = {
  data: {
    bio: string;
    date_of_birth: string;
    scores: Score[];
    links: {
      f?: SocialData;
      t?: SocialData;
      i?: SocialData;
      y?: SocialData;
      www?: SocialData;
      other?: SocialData;
    };
    homebase: string;
    homebase2: string;
    series: Series[];
  };
  userId: number;
};

const PersonalInfo: FC<PersonalInfoProps> = ({ data, userId }) => {
  const [showMoreSeries, setShowMoreSeries] = useState(false);
  const [type, setType] = useState<string>('nm');
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [toolTipVisible, setToolTipVisible] = useState<number | null>(null);

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

  const scores = ['NM1301', 'DARE', 'UN', 'UN+', 'TCC', 'SLOW', 'YES', 'WHS'];

  const handleOpenUrl = (url: string | undefined) => {
    url && Linking.openURL(url);
  };

  const hasActiveLinks = () => {
    return (
      (data.links?.f?.link && data.links?.f?.active !== 0) ||
      (data.links?.i?.link && data.links?.i?.active !== 0) ||
      (data.links?.t?.link && data.links?.t?.active !== 0) ||
      (data.links?.y?.link && data.links?.y?.active !== 0) ||
      (data.links?.www?.link && data.links?.www?.active !== 0) ||
      (data.links?.other?.link && data.links?.other?.active !== 0)
    );
  };

  const handleOpenModal = (type: string) => {
    switch (type) {
      case 'NM1301':
        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;
    }
    setIsModalVisible(true);
  };

  return (
    <>
      <ScrollView
        showsVerticalScrollIndicator={false}
        contentContainerStyle={{ gap: 20, paddingBottom: 32 }}
        style={{ paddingTop: 20 }}
      >
        <InfoItem inline={true} title={'RANKING'}>
          <View style={{ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between' }}>
            {scores.map((score, index) => {
              let scoreRank =
                data.scores?.find((s) => s.name === score && s.score > 0)?.score ?? '-';

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

              return (
                <TouchableOpacity
                  key={index}
                  style={styles.rankingItem}
                  onPress={() => handleOpenModal(score)}
                >
                  <Text style={styles.rankingScore}>{scoreRank}</Text>
                  <Text style={[styles.titleText, { flex: 0 }]}>
                    {score === 'NM1301' ? 'NM' : score}
                  </Text>
                </TouchableOpacity>
              );
            })}
          </View>
        </InfoItem>
        {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={{ display: 'flex', flexDirection: 'column', gap: 5, alignItems: 'center' }}
                  onPress={() => setToolTipVisible(index)}
                >
                  <Image
                    source={{ uri: API_HOST + data.icon_png }}
                    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}>DATE OF BIRTH</Text>
          <Text style={styles.titleText}>{new Date(data.date_of_birth).toDateString()}</Text>
        </View>
        <View style={{ display: 'flex', flexDirection: 'row' }}>
          <Text style={styles.headerText}>REGION OF ORIGIN</Text>
          <Text style={styles.titleText}>{data.homebase}</Text>
        </View>
        {data.homebase2 ? (
          <View style={{ display: 'flex', flexDirection: 'row' }}>
            <Text style={styles.headerText}>SECOND REGION</Text>
            <Text style={styles.titleText}>{data.homebase2}</Text>
          </View>
        ) : null} */}
        {data.bio && data.bio.length > 0 && (
          <InfoItem title={'BIO'}>
            <Text style={[styles.titleText, { flex: 0 }]}>{data.bio}</Text>
          </InfoItem>
        )}
        {hasActiveLinks() && (
          <InfoItem title={'SOCIAL LINKS'}>
            <View style={styles.linksBox}>
              {data.links?.f?.link && data.links?.f?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.f?.link)}>
                  <IconFacebook fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
              {data.links?.i?.link && data.links?.i?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.i?.link)}>
                  <IconInstagram fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
              {data.links?.t?.link && data.links?.t?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.t?.link)}>
                  <IconTwitter fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
              {data.links?.y?.link && data.links?.y?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.y?.link)}>
                  <IconYouTube fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
              {data.links?.www?.link && data.links?.www?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.www?.link)}>
                  <IconGlobe fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
              {data.links?.other?.link && data.links?.other?.active !== 0 ? (
                <TouchableOpacity onPress={() => handleOpenUrl(data.links?.other?.link)}>
                  <IconLink fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              ) : null}
            </View>
          </InfoItem>
        )}
      </ScrollView>
      <Modal
        isVisible={isModalVisible}
        onBackdropPress={() => setIsModalVisible(false)}
        onBackButtonPress={() => setIsModalVisible(false)}
        style={styles.modal}
        statusBarTranslucent={true}
        presentationStyle="overFullScreen"
      >
        <RegionsRenderer type={type} regions={regions} setIsModalVisible={setIsModalVisible} />
      </Modal>
    </>
  );
};

const InfoItem: FC<{
  title: string;
  inline?: boolean;
  children: ReactNode;
  showMore?: boolean;
}> = ({ title, inline, children, showMore }) => (
  <View>
    <Text style={[styles.headerText, { flex: 0 }]}>{title}</Text>
    <View
      style={[
        {
          display: 'flex',
          flexDirection: inline ? 'row' : 'column',
          justifyContent: 'space-evenly',
          marginTop: 10
        },
        showMore ? { flexWrap: 'wrap', gap: 8 } : {}
      ]}
    >
      {children}
    </View>
  </View>
);

const UnauthenticatedProfileScreen = () => {
  const navigation = useNavigation();

  return (
    <PageWrapper>
      <View style={{ marginTop: 15, display: 'flex', gap: 10 }}>
        <BigText children={'You are not logged in. Please login or register to access profile.'} />
        <Button
          onPress={() =>
            navigation.dispatch(
              CommonActions.reset({
                index: 1,
                routes: [{ name: NAVIGATION_PAGES.WELCOME }]
              })
            )
          }
          variant={ButtonVariants.FILL}
        >
          Go to login/register
        </Button>
      </View>
    </PageWrapper>
  );
};

export default ProfileScreen;
