import { useState, useEffect } from "react";
import { graphql, readInlineData } from "react-relay";
import { Link } from "react-router-dom";
import { AlertCircle } from "lucide-react";
import { validate, type LexiconDoc } from "@slices/lexicon";
import type { LexiconTree_lexicon$key } from "../__generated__/LexiconTree_lexicon.graphql.ts";

export const LexiconFragment = graphql`
  fragment LexiconTree_lexicon on NetworkSlicesLexicon @inline {
    uri
    nsid
    description
    definitions
    createdAt
    updatedAt
  }
`;

type LexiconData = {
  uri: string;
  nsid: string;
  description: string | null | undefined;
  definitions: string;
  createdAt: string;
  updatedAt: string | null | undefined;
};

interface LexiconTreeProps {
  lexicons: ReadonlyArray<LexiconTree_lexicon$key>;
  handle: string;
  sliceRkey: string;
}

export function LexiconTree({ lexicons, handle, sliceRkey }: LexiconTreeProps) {
  // Read fragment data for each lexicon
  const lexiconData = lexicons.map((lexicon) =>
    readInlineData(LexiconFragment, lexicon)
  );

  // Track which lexicons are invalid
  const [invalidLexicons, setInvalidLexicons] = useState<Set<string>>(new Set());

  // Validate all lexicons together
  useEffect(() => {
    const validateLexicons = async () => {
      try {
        // Convert lexicons to validator format
        const lexiconsForValidation: LexiconDoc[] = [];
        for (const lex of lexiconData) {
          try {
            lexiconsForValidation.push({
              id: lex.nsid,
              defs: JSON.parse(lex.definitions),
              lexicon: 1,
              description: lex.description || undefined,
            });
          } catch {
            // If we can't parse the definitions, mark as invalid
          }
        }

        // Validate all lexicons
        const validationResult = await validate(lexiconsForValidation);

        if (validationResult !== null) {
          // validationResult is a map of lexicon ID to array of error strings
          setInvalidLexicons(new Set(Object.keys(validationResult)));
        } else {
          setInvalidLexicons(new Set());
        }
      } catch (error) {
        console.error("Failed to validate lexicons:", error);
      }
    };

    validateLexicons();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [lexicons]);

  return (
    <div>
      {lexiconData.map((lexicon, index) => {
        const rkey = lexicon.uri.split("/").pop();
        const parts = lexicon.nsid.split(".");
        const authority = parts.length >= 2 ? `${parts[0]}.${parts[1]}` : parts[0];
        const rest = parts.length >= 2 ? parts.slice(2).join(".") : "";

        // Check if this is a record type lexicon
        let isRecordType = false;
        try {
          const definitions = JSON.parse(lexicon.definitions);
          isRecordType = definitions.main?.type === "record";
        } catch (e) {
          console.error("Failed to parse lexicon definitions:", lexicon.nsid, e);
        }

        // Check if this is the first item or if the authority changed from previous item
        const prevLexicon = index > 0 ? lexiconData[index - 1] : null;
        const prevParts = prevLexicon?.nsid.split(".");
        const prevAuthority = prevParts && prevParts.length >= 2
          ? `${prevParts[0]}.${prevParts[1]}`
          : prevParts?.[0];
        const showBreak = index > 0 && authority !== prevAuthority;

        // Check if this lexicon is invalid
        const isInvalid = invalidLexicons.has(lexicon.nsid);

        // Split the rest into middle and last part if it's a record type
        let middle = rest;
        let lastPart = "";
        if (isRecordType && rest) {
          const restParts = rest.split(".");
          if (restParts.length > 1) {
            lastPart = restParts[restParts.length - 1];
            middle = restParts.slice(0, -1).join(".");
          } else {
            lastPart = rest;
            middle = "";
          }
        }

        return (
          <div key={lexicon.uri}>
            {showBreak && <div className="h-3" />}
            <Link
              to={`/profile/${handle}/slice/${sliceRkey}/lexicons/${rkey}`}
              state={{ lexicon }}
              className="flex items-center gap-2 py-1 cursor-pointer hover:bg-zinc-900/50 rounded group"
            >
              {isInvalid && (
                <AlertCircle size={14} className="text-red-500 flex-shrink-0" />
              )}
              <span className={`text-sm font-medium font-mono group-hover:text-zinc-100 transition-colors ${isInvalid ? "text-red-400" : ""}`}>
                <span className={isInvalid ? "text-red-400" : "text-zinc-200"}>{authority}</span>
                {isRecordType ? (
                  <>
                    {middle && <span className={isInvalid ? "text-red-400" : "text-zinc-400"}>.{middle}</span>}
                    {lastPart && (
                      <>
                        <span className={isInvalid ? "text-red-400" : "text-zinc-400"}>.</span>
                        <span className={isInvalid ? "text-red-400" : "text-cyan-400"}>{lastPart}</span>
                      </>
                    )}
                  </>
                ) : (
                  rest && <span className={isInvalid ? "text-red-400" : "text-zinc-400"}>.{rest}</span>
                )}
              </span>
              {lexicon.description && (
                <span className="text-xs text-zinc-600 truncate">
                  {lexicon.description}
                </span>
              )}
            </Link>
          </div>
        );
      })}
    </div>
  );
}
