import React, { useEffect, useState } from 'react';
import { View, Platform, SafeAreaView, Text } from 'react-native';
import MapView, { Geojson, UrlTile } from 'react-native-maps';

import kye from '../../../../../assets/geojson/kye.json';
import { Header } from 'src/components';
import { useGetKyeQuery, usePostSetKye } from '@api/travels';
import { StoreType, storage } from 'src/storage';

import { FeatureCollection } from '@turf/turf';
import { MAP_HOST } from 'src/constants';
import { styles } from './styles';

interface PropertiesData {
  id: number;
  tt: string;
  mega: string;
  name: string;
  fill?: string;
}

const EarthScreen = () => {
  const token = storage.get('token', StoreType.STRING) as string;
  const [geojson, setGeojson] = useState<FeatureCollection>(kye as FeatureCollection);
  const { data } = useGetKyeQuery(token, true);
  const { mutateAsync } = usePostSetKye();
  const [visited, setVisited] = useState<number[]>([]);
  const [score, setScore] = useState({ base: 0, percentage: 0 });
  const [quadrantsAll, setQuadrantsAll] = useState<number>(1);

  useEffect(() => {
    if (!data || !data.regions) return;
    setQuadrantsAll(data.regions?.length);
    token && setVisited(data.visited);
  }, [data]);

  useEffect(() => {
    const updatedGeojson = updateGeojsonStyles(geojson);
    setGeojson(updatedGeojson);
    showScore();
  }, [visited]);

  const getFeatureStyle = (properties: PropertiesData) => {
    const style = {
      fill: 'transparent'
    };

    if (properties.tt == '1') {
      if (properties.id > 612) {
        if (Math.max(...visited) > 612) {
          style.fill = 'rgba(132, 138, 68, 0.5)';
        } else {
          style.fill = 'rgba(21, 99, 123, 0.5)';
        }
      } else {
        if (visited.includes(properties.id)) {
          style.fill = 'rgba(132, 138, 68, 0.5)';
        } else {
          style.fill = 'rgba(21, 99, 123, 0.5)';
        }
      }
    } else {
      style.fill = 'rgba(230, 230, 230, 0.5)';
    }

    return style;
  };

  const updateGeojsonStyles = (geojson: FeatureCollection) => {
    const updatedFeatures = geojson.features.map((feature) => {
      const style = getFeatureStyle(feature.properties as PropertiesData);
      return { ...feature, properties: { ...feature.properties, ...style } };
    });

    return { ...geojson, features: updatedFeatures };
  };

  const markQuadrant = async (qid: number) => {
    if (!token) return;

    let vis: 0 | 1 = 1;
    if (qid > 612) {
      if (Math.max(...visited) > 612) {
        vis = 0;
      }
    } else {
      if (visited.includes(qid)) {
        vis = 0;
      }
    }

    try {
      await mutateAsync(
        { token, qid, visited: vis },
        {
          onSuccess: () => {
            if (vis == 0) {
              quadRemove(qid);
            } else {
              quadAdd(qid);
            }
          }
        }
      );
    } catch (error) {
      console.error('Failed to update kye state', error);
    }
  };

  const quadAdd = (qid: number) => {
    setVisited((prevVisited) => {
      if (qid > 612) {
        const newVisited = [...prevVisited];
        for (let i = 613; i < 649; i++) {
          if (!newVisited.includes(i)) {
            newVisited.push(i);
          }
        }
        return newVisited;
      } else {
        if (!prevVisited.includes(qid)) {
          return [...prevVisited, qid];
        }
        return prevVisited;
      }
    });
  };

  const quadRemove = (qid: number) => {
    setVisited((prevVisited) => {
      if (qid > 612) {
        return prevVisited.filter((id) => id < 613 || id > 648);
      } else {
        return prevVisited.filter((id) => id !== qid);
      }
    });
  };

  const showScore = () => {
    let baseList = visited.filter((id) => id < 613);
    let score = baseList.length;
    if (Math.max(...visited) > 612) {
      score += 1;
    }
    let calc = Math.round((score / quadrantsAll) * 10000) / 100;
    setScore({ base: score, percentage: calc });
  };

  return (
    <SafeAreaView style={{ height: '100%' }}>
      <View style={styles.wrapper}>
        <Header label={'My Earth'} />
        {token && (
          <View style={styles.score}>
            <Text style={[styles.scoreText, { fontWeight: 'bold' }]}>Your score: {score.base}</Text>
            <Text style={[styles.scoreText, { fontSize: 14 }]}>{`(${score.percentage}%)`}</Text>
          </View>
        )}
      </View>

      <View style={styles.container}>
        <MapView
          style={styles.map}
          showsMyLocationButton={false}
          showsCompass={false}
          zoomControlEnabled={false}
          mapType={Platform.OS == 'android' ? 'none' : 'standard'}
          maxZoomLevel={15}
          minZoomLevel={0}
          initialRegion={{
            latitude: 0,
            longitude: 0,
            latitudeDelta: 180,
            longitudeDelta: 180
          }}
        >
          <UrlTile
            urlTemplate={`${MAP_HOST}/tiles_osm/{z}/{x}/{y}`}
            maximumZ={15}
            maximumNativeZ={13}
            shouldReplaceMapContent
            minimumZ={0}
          />
          <Geojson
            geojson={geojson as any}
            zIndex={1}
            tappable={true}
            onPress={(event) => {
              markQuadrant(event.feature.properties?.id);
            }}
            tracksViewChanges={false}
          />
        </MapView>
      </View>
    </SafeAreaView>
  );
};

export default EarthScreen;
