import React, { useEffect, useRef, useState } from 'react';
import { View, Platform, Text, StatusBar } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

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 { VECTOR_MAP_HOST } from 'src/constants';
import { styles } from './styles';
import * as MapLibreRN from '@maplibre/maplibre-react-native';

let kye_fill = {
  id: 'kye_fill',
  style: {
    fillColor: 'rgba(21, 99, 123, 0.4)'
  },

  maxzoom: 12
};

let kye_fill_visited = {
  id: 'kye_fill_visited',
  style: {
    fillColor: 'rgba(132, 138, 68, 0.6)'
  },
  maxzoom: 12
};

let kye_line = {
  id: 'kye_line',
  filter: ['all'],
  style: {
    lineColor: 'rgba(14, 80, 109, 1)',
    lineWidth: ['interpolate', ['linear'], ['zoom'], 0, 0.8, 4, 1, 5, 1.5, 12, 3],
    lineWidthTransition: { duration: 300, delay: 0 }
  },
  maxzoom: 16
};

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

  const generateFilter = (ids: number[]) => {
    if (!ids || !ids.length) return ['==', 'id', -1];

    return [
      'any',
      ...ids.map((id) => {
        if (id > 612) {
          return ['>=', 'id', 613];
        } else {
          return ['==', 'id', id];
        }
      })
    ];
  };

  const [filter, setFilter] = useState<any[]>(generateFilter([]));

  const mapRef = useRef<MapLibreRN.MapViewRef>(null);

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

  useEffect(() => {
    setFilter(generateFilter(visited));
    showScore();
  }, [visited]);

  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 });
  };

  const onMapPress = async (event: any) => {
    if (!mapRef.current) return;

    try {
      const { screenPointX, screenPointY } = event.properties;

      const { features } = await mapRef.current.queryRenderedFeaturesAtPoint(
        [screenPointX, screenPointY],
        undefined,
        ['kye_fill']
      );

      if (features?.length) {
        const selectedKye = features[0];

        if (selectedKye.properties && selectedKye.properties.tt == '1') {
          markQuadrant(selectedKye.properties.id);
        }
      }
    } catch (error) {
      console.error('Failed to get coordinates on EarthScreen', error);
    }
  };

  return (
    <SafeAreaView style={{ height: '100%' }} edges={['top']}>
      <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,
          { paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0 }
        ]}
      >
        <MapLibreRN.MapView
          ref={mapRef}
          style={styles.map}
          mapStyle={VECTOR_MAP_HOST + '/nomadmania-maps.json'}
          rotateEnabled={false}
          attributionEnabled={false}
          onPress={onMapPress}
        >
          <MapLibreRN.ShapeSource id="kye" shape={kye as any}>
            <MapLibreRN.LineLayer
              id={kye_line.id}
              filter={kye_line.filter as any}
              maxZoomLevel={kye_line.maxzoom}
              style={kye_line.style as any}
              belowLayerID="waterway-name"
            />
            <MapLibreRN.FillLayer
              id={kye_fill.id}
              filter={['==', 'tt', '1']}
              style={kye_fill.style}
              maxZoomLevel={kye_fill.maxzoom}
              belowLayerID={kye_fill_visited.id}
            />
            <MapLibreRN.FillLayer
              id={kye_fill_visited.id}
              filter={filter as any}
              style={kye_fill_visited.style}
              maxZoomLevel={kye_fill_visited.maxzoom}
              belowLayerID={kye_line.id}
            />
          </MapLibreRN.ShapeSource>
        </MapLibreRN.MapView>
      </View>
    </SafeAreaView>
  );
};

export default EarthScreen;
