"use client";
import React, { useState, useEffect } from 'react';
import positions from "@/data/positions.json";
import server_matrix from "@/data/server_matrix.json";
import server_names from "@/data/server_names.json";
import tag_names from "@/data/tag_names.json";
import { cosineSimilarity, averageOfArrays } from "@/utils/math";
import { ServerCards } from "@/components/server_cards";
import type { Tag } from "@/utils/types";
import { isSensitive } from "@/utils/types";
//import { selected_tags, find_most_similar_tags } from '@/app/page';
import { selected_tags, find_most_similar_tags } from '@/utils/types';
import { SensativeSelector } from './SensativeSelector';
import { TagSearch } from './tag_search';

export const TagSelector: React.FC = () => {
  //const top_tags: Tag[] = [];
  const all_tags: Tag[] = tag_names.map((tag: string, index: number) => ({ index, tag }));
  const tags: Tag[] = all_tags.filter((tag: Tag) => selected_tags.includes(tag.tag));

  // state
  const [selectedTagIds, setSelectedTagIds] = useState<number[]>([]);
  const [suggestedTagIds, setSuggestedTagIds] = useState<number[]>([]);
  const [topServerIds, setTopServerIds] = useState<number[]>([]);
  const [showSensitiveTags, setShowSensitiveTags] = useState<boolean>(false);

  // Function to handle tag selection toggling.
  const toggleTag = (tagId: number) => {
    setSelectedTagIds((currentTagIds) => currentTagIds.includes(tagId)
      ? currentTagIds.filter((id) => id !== tagId)
      : [...currentTagIds, tagId]
    );
  };

  useEffect(() => {
    // get the average position of all selected tags
    if (selectedTagIds.length == 0) {
      setTopServerIds([]);
      setSuggestedTagIds([]);
    } else {
      let selected_positions = selectedTagIds.map((tagId) => positions[tagId]);
      // get the average of selected positions
      let average_position = averageOfArrays(selected_positions);
      // loop through each row of the server_matrix and calculate the cosine similarity
      const server_similarity = averageOfArrays(selected_positions.map((pos) => server_matrix.map((row) => cosineSimilarity(pos, row))));
      //console.log(server_similarity);
      const server_rank = server_similarity.map((similarity, index) => ({ index, similarity })).sort((a, b) => b.similarity - a.similarity).map((item, index) => ({ index: item.index, similarity: item.similarity, name: server_names[item.index] }));
      //console.log(server_rank);
      setTopServerIds(server_rank.slice(0, 25).map((item) => item.index));
      // Find the most similar tags among all tags
      const tag_similarity = all_tags.map((tag) => ({ t: tag, sim: cosineSimilarity(average_position, positions[tag.index]) })).sort((a, b) => b.sim - a.sim);
      const most_similar = find_most_similar_tags(all_tags, tag_names, selectedTagIds, positions);
      setSuggestedTagIds(most_similar.map((tag) => tag.index));
    }
  }, [selectedTagIds, all_tags]);

  return (
    <div>
      <div className="flex flex-wrap gap-2">
        <div>
          <h1 className='text-3xl font-bold'>Mastodon Server Reccomender</h1>
          <div className='grid grid-flow-row-dense grid-cols-3'>
            <div className='mr-3 mb-2 p-3 bg-gray-100 col-span-2'>
              <h3>Search</h3>
              <TagSearch all_tags={all_tags} selectedTagIds={selectedTagIds} onToggle={toggleTag} />
            </div>
            <div className='mr-3 mb-2 p-3'>
              <h3>Settings</h3>
              <SensativeSelector 
                showSensitiveTags={showSensitiveTags}
                setShowSensitiveTags={setShowSensitiveTags}
              />
            </div>
          </div>
          {/*<div>
              <p>Languages</p>
              <select value={"en"}>
                {locales.map((locale) => (
                  <option key={locale.code} value={locale.code}>{locale.language}</option>
                ))}
              </select>
              </div>*/}
          <h3>Selected</h3>
          {all_tags.filter((tag) => selectedTagIds.includes(tag.index)).map((tag) => (
            <button
              key={tag.index}
              onClick={() => toggleTag(tag.index)}
              className={`px-3 py-1 m-1 rounded-full text-sm ${selectedTagIds.includes(tag.index) ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'} transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-50`}
            >
              {tag.tag}
            </button>
          ))}
        </div>
        <div>
          <h3>Categories</h3>
          {tags.filter((tag) => !selectedTagIds.includes(tag.index)).map((tag) => (
            <button
              key={tag.index}
              onClick={() => toggleTag(tag.index)}
              className={`px-3 py-1 m-1 rounded-full text-sm bg-gray-200 text-gray-800 transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-50`}
            >
              {tag.tag}
            </button>
          ))}
        </div>
        <div>
          <h3>Suggested Tags ({suggestedTagIds.filter((tag) => !selectedTagIds.includes(tag)).length})</h3>
          {all_tags.filter((tag) => suggestedTagIds.includes(tag.index)).filter(
            (tag) => !selectedTagIds.includes(tag.index)
          ).filter(
            (tag) => showSensitiveTags || !isSensitive(tag)
          ).map((tag) => (
            <button
              key={tag.index}
              onClick={() => toggleTag(tag.index)}
              className={`px-3 py-1 m-1 rounded-full text-sm ${isSensitive(tag) ? 'bg-red-200' : 'bg-gray-200'} text-gray-800 transition-colors duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-50`}
            >
              {isSensitive(tag) ? tag.tag.split('_')[0] : tag.tag}
            </button>
          ))}
        </div>
      </div>
      <div>
        <ul>
          <ServerCards topServerIds={topServerIds} tagCount={selectedTagIds.length} />
        </ul>
      </div>
    </div>
  );
};
