import React, { FC, ReactNode, useState } from 'react';
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
import { Image } from 'expo-image';
import { CommonActions, NavigationProp, useNavigation } from '@react-navigation/native';

import {
  type Score,
  type Series,
  type SocialData,
  usePostGetProfileInfoPublicQuery,
  usePostGetProfileInfoQuery
} 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';

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;

  if (!token) return <UnauthenticatedProfileScreen />;

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

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

  return (
    <PageWrapper>
      {isPublicView && <Header label="Profile" />}
      <View style={[styles.pageWrapper, isPublicView && { marginTop: 0 }]}>
        <View>
          {data.avatar ? (
            <Image
              style={{ borderRadius: 64 / 2, width: 64, height: 64 }}
              source={{ uri: API_HOST + data.avatar }}
            />
          ) : (
            <AvatarWithInitials
              text={`${data.first_name[0] ?? ''}${data.last_name[0] ?? ''}`}
              flag={API_HOST + data.homebase_flag}
              size={64}
            />
          )}
        </View>
        <View style={{ gap: 5, width: '75%' }}>
          <Text style={[styles.headerText, { fontSize: getFontSize(18), flex: 0 }]}>
            {data.first_name} {data.last_name}
          </Text>
          <View style={{ display: 'flex', justifyContent: 'space-between', flexDirection: 'row' }}>
            <View
              style={{
                display: 'flex',
                flexDirection: 'row',
                gap: 10,
                alignItems: 'center'
              }}
            >
              <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 ? (
              <View>
                <TouchableOpacity onPress={() => navigation.navigate(NAVIGATION_PAGES.SETTINGS)}>
                  <GearIcon fill={Colors.DARK_BLUE} />
                </TouchableOpacity>
              </View>
            ) : 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
        }}
      />
    </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[];
  };
};

const PersonalInfo: FC<PersonalInfoProps> = ({ data }) => {
  const [showMoreSeries, setShowMoreSeries] = useState(false);

  return (
    <ScrollView
      showsVerticalScrollIndicator={false}
      contentContainerStyle={{ gap: 20 }}
      style={{ marginTop: 20 }}
    >
      <InfoItem inline={true} title={'RANKING'}>
        <View style={{ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between' }}>
          {data.scores?.map((data, index) => {
            if (!data.score) return null;
            return (
              <View key={index} style={styles.rankingItem}>
                <Text style={[styles.headerText, { flex: 0 }]}>{data.score}</Text>
                <Text style={[styles.titleText, { flex: 0 }]}>{data.name}</Text>
              </View>
            );
          })}
        </View>
      </InfoItem>
      <InfoItem showMore={showMoreSeries} inline={true} title={'SERIES BADGES'}>
        {data.series?.slice(0, showMoreSeries ? data.series.length : 8).map((data, index) => (
          <View
            key={index}
            style={{ display: 'flex', flexDirection: 'column', gap: 5, alignItems: 'center' }}
          >
            <Image source={{ uri: API_HOST + data.icon_png }} style={{ width: 28, height: 28 }} />
            <Text style={[styles.headerText, { flex: 0 }]}>{data.score}</Text>
          </View>
        ))}
      </InfoItem>
      {data.series?.length > 8 ? (
        <Button
          children={showMoreSeries ? 'Hide series' : 'Show more'}
          variant={ButtonVariants.TEXT}
          onPress={() => setShowMoreSeries(!showMoreSeries)}
        />
      ) : 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}
      <InfoItem title={'BIO'}>
        <Text style={[styles.titleText, { flex: 0 }]}>{data.bio}</Text>
      </InfoItem>
      <InfoItem title={'SOCIAL LINKS'}>
        <View style={{ display: 'flex', flexDirection: 'row', gap: 15, alignItems: 'center' }}>
          {data.links?.f?.link ? <IconFacebook fill={Colors.DARK_BLUE} /> : null}
          {data.links?.i?.link ? <IconInstagram fill={Colors.DARK_BLUE} /> : null}
          {data.links?.t?.link ? <IconTwitter fill={Colors.DARK_BLUE} /> : null}
          {data.links?.y?.link ? <IconYouTube fill={Colors.DARK_BLUE} /> : null}
          {data.links?.www?.link ? <IconGlobe fill={Colors.DARK_BLUE} /> : null}
          {data.links?.other?.link ? <IconLink fill={Colors.DARK_BLUE} /> : null}
        </View>
      </InfoItem>
    </ScrollView>
  );
};

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;
