"use client";

import { Spinner } from "@/components/ui/spinner";
import { useState, useEffect, useTransition, useRef, useCallback } from "react";
import { WordData } from "@/zoom/logic/types";
import {
  fetchWordsByToneAndSyllables,
  mutateToneSelection,
} from "@/actions/tones";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton"; // For loading state
import { MutationOrder, ToneQuery } from "@/lib/types/phonetics";
import { ProsodySyllable } from "@/lib/types/cards";
import { ArrowLeft, ArrowRight, Volume2 } from "lucide-react";

function getColorByTone(tone: string): string {
  if (tone === "mid") return "blue";
  if (tone === "low") return "green";
  if (tone === "falling") return "gold";
  if (tone === "high") return "purple";
  if (tone === "rising") return "black";
  else return "black";
}
// Helper to display tones prominently
const ProminentToneDisplay = ({ word }: { word: any }) => {
  const [isLoading, setLoading] = useState(false);
  const tones: string[] = word.tone_sequence.split(",");
  const syls: string[] = word.syl_seq.split(",");
  const [isPending, startTransition] = useTransition();
  function mutateWord(idx: number) {
    console.log("changing", idx);
    const mutationOrder: MutationOrder = syls.map((s, i) => {
      if (idx === i) return { change: tones[idx]! };
      else return { keep: syls[i]! };
    });
    console.log("hey hey", word);
    startTransition(async () => {
      const words = await mutateToneSelection(mutationOrder);
      console.log({ words });
      // setCurrentWord(word);
    });
  }
  // playing audio
  // const sourceRef = useRef<AudioBufferSourceNode>(null);
  const audioRef = useRef<HTMLAudioElement>(null);

  async function playAudio() {
    setLoading(true);
    // const audioContext = new (window.AudioContext ||
    //   (window as any).webkitAudioContext)();
    // const response = await fetch(audioUrl);
    // const arrayBuffer = await response.arrayBuffer();
    // const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
    // if (audioContext && audioBuffer) {
    //   setLoading(false);
    //   const source = audioContext.createBufferSource();
    //   source.buffer = audioBuffer;
    //   source.connect(audioContext.destination);
    //   source.start();
    //   sourceRef.current = source;
    // }
    const res = await fetch(`/api/tts?word=${word.spelling}&lang=thai`);
    const audioBlob = await res.blob();
    const audioURL = URL.createObjectURL(audioBlob);
    setLoading(false);
    if (audioRef.current) {
      audioRef.current.src = audioURL;
      audioRef.current.play();
    }
  }
  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === " ") {
        e.preventDefault();
        playAudio();
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [playAudio]);

  return (
    <div className="flex flex-col items-center mb-4">
      <h1 className="text-6xl font-bold mb-2">
        {syls.map((syl: string, idx: number) => (
          <span
            key={syl + idx}
            onClick={() => mutateWord(idx)}
            style={{ color: getColorByTone(tones[idx]!) }}
            className="cursor-pointer hover:text-gray-700"
          >
            {syl}
          </span>
        ))}
      </h1>
      <div className="mt-4 space-x-4">
        <p className="ipa text-xl text-gray-700 mt-2">{word.ipa}</p>
        <button
          className="p-1 text-blue-500 hover:text-blue-700 transition-colors"
          title="Pronounce"
          onClick={playAudio}
        >
          <Volume2 size={20} />
        </button>
        {(isPending || isLoading) && <Spinner />}
        <audio ref={audioRef} />
        <p className="ipa text-xl text-gray-700 mt-2">{word.frequency}</p>
        <p className="ipa text-xl text-gray-700 mt-2">{word.word_id}</p>
      </div>
    </div>
  );
};

export default function ToneSelectorClient({
  initialData,
  initialTones,
}: {
  initialData: any[];
  initialTones: ToneQuery;
}) {
  const [data, setData] = useState<any[]>(initialData);
  const [currentIdx, setCurrentIdx] = useState(0);
  const [isLoading, startTransition] = useTransition();
  const [selectedTones, setTones] = useState<ToneQuery>(initialTones);

  const goPrev = useCallback(() => {
    setCurrentIdx((i) => (i === 0 ? 0 : i - 1));
  }, []);
  const goNext = useCallback(() => {
    setCurrentIdx((i) => (i === data.length - 1 ? data.length - 1 : i + 1));
  }, [data.length]);

  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "ArrowLeft") {
        e.preventDefault();
        goPrev();
      } else if (e.key === "ArrowRight") {
        e.preventDefault();
        goNext();
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [goPrev, goNext]);

  const handleFetch = () => {
    startTransition(async () => {
      const words = await fetchWordsByToneAndSyllables(selectedTones);
      setData(words);
    });
  };

  return (
    <div className="container mx-auto p-4 max-w-2xl">
      <ToneForm
        isLoading={isLoading}
        handleFetch={handleFetch}
        selectedTones={selectedTones}
        setTones={setTones}
      />

      <Inner
        isLoading={isLoading}
        currentWord={data[currentIdx]}
        goPrev={goPrev}
        goNext={goNext}
      />
    </div>
  );
}
type IProps = {
  isLoading: boolean;
  currentWord: any;
  goPrev: () => void;
  goNext: () => void;
};
function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) {
  return isLoading ? (
    <Card>
      <CardHeader>
        <Skeleton className="h-12 w-3/4" />
      </CardHeader>
      <CardContent className="space-y-4">
        <Skeleton className="h-8 w-1/2" />
        <Skeleton className="h-20 w-full" />
        <Skeleton className="h-6 w-full" />
      </CardContent>
    </Card>
  ) : currentWord ? (
    <Card>
      <CardHeader>
        <CardTitle className="text-center">Current Word</CardTitle>
      </CardHeader>
      <CardContent>
        <ProminentToneDisplay word={currentWord} />
        {/* You can add more details from WordData here if needed, like definitions */}
      </CardContent>
      <CardFooter className="justify-between">
        <ArrowLeft onClick={goPrev} />
        <ArrowRight onClick={goNext} />
      </CardFooter>
    </Card>
  ) : (
    <Card>
      <CardHeader>
        <CardTitle className="text-center">No Word Found</CardTitle>
      </CardHeader>
      <CardContent>
        <p className="text-center text-gray-600">
          Could not find a Thai word matching your criteria. Try different
          selections.
        </p>
      </CardContent>
    </Card>
  );
}

type ToneFormProps = {
  isLoading: boolean;
  handleFetch: (tones: ToneQuery) => void;
  selectedTones: ToneQuery;
  setTones: React.Dispatch<React.SetStateAction<ToneQuery>>;
};
function ToneForm({
  selectedTones,
  setTones,
  isLoading,
  handleFetch,
}: ToneFormProps) {
  const thaiTones = [
    { value: "mid", label: "1 (Mid)" },
    { value: "low", label: "2 (Low)" },
    { value: "falling", label: "3 (Falling)" },
    { value: "high", label: "4 (High)" },
    { value: "rising", label: "5 (Rising)" },
  ];
  const [syllableCount, setSyllableCount] = useState<number>(2);
  const decrSyl = useCallback(() => {
    setSyllableCount((s) => (s <= 1 ? 1 : s - 1));
  }, []);
  const incrSyl = useCallback(() => {
    setSyllableCount((s) => (s >= 5 ? 5 : s + 1));
  }, []);

  useEffect(() => {
    // Adjust selectedTones array length when syllableCount changes
    setTones((prevTones) => {
      const newTones = Array(syllableCount).fill(null);
      for (let i = 0; i < Math.min(prevTones.length, syllableCount); i++) {
        newTones[i] = prevTones[i];
      }
      return newTones;
    });
  }, [syllableCount]);

  const handleSyllableCountChange = (value: string) => {
    const count = parseInt(value, 10);
    if (!isNaN(count) && count > 0 && count <= 5) {
      // Max 5 syllables for simplicity
      setSyllableCount(count);
    }
  };

  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "ArrowUp") {
        e.preventDefault();
        incrSyl();
      } else if (e.key === "ArrowDown") {
        e.preventDefault();
        decrSyl();
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [incrSyl, decrSyl]);

  const handleToneChange = (syllableIndex: number, value: string) => {
    const tone = value === "any" ? null : value;
    setTones((prevTones) => {
      const newTones = [...prevTones];
      newTones[syllableIndex] = tone;
      return newTones;
    });
  };

  return (
    <Card className="mb-6">
      <CardHeader>
        <CardTitle>Thai Tone Explorer</CardTitle>
        <CardDescription>
          Select syllable count and tones to find Thai words.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <div className="flex gap-10 justify-center">
          {Array.from({ length: syllableCount }).map((_, index) => (
            <div key={index} className="w-fit">
              <Select
                value={selectedTones[index]?.toString() || "any"}
                onValueChange={(value) => handleToneChange(index, value)}
              >
                <SelectTrigger
                  id={`tone-select-${index}`}
                  className="w-full md:w-full mt-1"
                >
                  <SelectValue
                    className="w-full"
                    placeholder={`Select tone for syllable ${index + 1}`}
                  />
                </SelectTrigger>
                <SelectContent className="lolol md:w-full bg-white w-full">
                  <SelectItem value="any">Any Tone</SelectItem>
                  {thaiTones.map((tone) => (
                    <SelectItem key={tone.value} value={tone.value}>
                      {tone.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          ))}
        </div>
      </CardContent>
      <CardFooter className="justify-center gap-18">
        <Button className="" onClick={decrSyl}>
          -
        </Button>
        <Button
          onClick={() => handleFetch(selectedTones)}
          disabled={isLoading}
          className="w-full md:w-auto"
        >
          {isLoading ? "Searching..." : "Fetch"}
        </Button>
        <Button className="" onClick={incrSyl}>
          +
        </Button>
      </CardFooter>
    </Card>
  );
}
