import apiFetch from "@/lib/apiFetch";
import {
  Button,
  Card,
  Container,
  Group,
  List,
  Stack,
  Textarea,
  TextInput,
  Title,
} from "@mantine/core";
import { useLocalStorage, useShallowEffect } from "@mantine/hooks";
import { showNotification } from "@mantine/notifications";
import { useState } from "react";
import useSWR from "swr";

export default function TiktokTtsPage() {
  useShallowEffect(() => {
    const chat = apiFetch.api["tts-tiktok"].ws.subscribe();
    chat.subscribe((message) => {
      console.log("got", message);
    });

    chat.on("open", () => {
      chat.send("hello from client");
    });
  }, []);

  return (
    <Container size={"md"} w={"100%"}>
      <Stack gap="lg">
        <Title order={4}>Tiktok TTS</Title>
        <GenerateTts />
        <ListAudio />
      </Stack>
    </Container>
  );
}

function GenerateTts() {
  const [fileName, setFileName] = useLocalStorage({
    key: "fileName",
    defaultValue: "",
  });
  const [session_id, setSessionId] = useLocalStorage({
    key: "session_id",
    defaultValue: "",
  });
  const [text, setText] = useLocalStorage({
    key: "text",
    defaultValue: "",
  });

  const [loading, setLoading] = useState(false);

  const generate = async () => {
    try {
      setLoading(true);
      if (!session_id || !text || !fileName)
        return showNotification({
          title: "Error",
          message: "Session ID atau Text tidak boleh kosong",
          color: "red",
        });
      const { data } = await apiFetch.api["tts-tiktok"].generate.post({
        text,
        sessionId: session_id,
        file_name: fileName,
      });
      console.log(data);
      showNotification({
        title: "Success",
        message: "TTS berhasil di generate",
        color: "green",
      });

      setText("");
    } catch (error) {
      showNotification({
        title: "Error",
        message: "Gagal generate TTS",
        color: "red",
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <Card shadow="sm" radius="md" padding="lg">
      <Stack gap="md">
        <Title order={4}>Generate TTS</Title>
        <TextInput
          placeholder="session_id"
          value={session_id}
          onChange={(e) => setSessionId(e.currentTarget.value)}
        />
        <TextInput
          placeholder="file_name"
          value={fileName}
          onChange={(e) => setFileName(e.currentTarget.value)}
        />
        <Textarea
          placeholder="text"
          autosize
          minRows={3}
          maxRows={10}
          value={text}
          onChange={(e) => setText(e.currentTarget.value)}
        />
        <Group>
          <Button onClick={generate} loading={loading}>
            Generate
          </Button>
        </Group>
      </Stack>
    </Card>
  );
}

function ListAudio() {
  const { data, error, isLoading, mutate } = useSWR(
    "/x",
    apiFetch.api["tts-tiktok"]["list-audio"].get,
    { refreshInterval: 3000, revalidateOnFocus: true },
  );

  const [audioUrl, setAudioUrl] = useState<string | null>(null);

  const playAudio = async (filename: string) => {
    const { error, response } = await apiFetch.api["tts-tiktok"]
    ["download"]({ filename })
      .get();

    if (error) {
      showNotification({
        title: "Error",
        message: "Gagal download audio",
        color: "red",
      });
      return;
    }

    const res = await fetch(response.url);
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    setAudioUrl(url);
  };

  const downloadAudio = async (filename: string) => {
    const { error, response } = await apiFetch.api["tts-tiktok"]
    ["download"]({ filename })
      .get();

    if (error) {
      showNotification({
        title: "Error",
        message: "Gagal download file",
        color: "red",
      });
      return;
    }

    const res = await fetch(response.url);
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);

    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(url);
  };

  const deleteAudio = async (filename: string) => {
    const { error } = await apiFetch.api["tts-tiktok"]
      .remove({ filename })
      .delete();

    if (error) {
      showNotification({
        title: "Error",
        message: "Gagal menghapus file",
        color: "red",
      });
      return;
    }

    showNotification({
      title: "Success",
      message: `File ${filename} dihapus`,
      color: "green",
    });

    mutate(); // refresh list
  };

  const deleteAll = async () => {
    const { error } = await apiFetch.api["tts-tiktok"].clear.delete();

    if (error) {
      showNotification({
        title: "Error",
        message: "Gagal menghapus semua file",
        color: "red",
      });
      return;
    }

    showNotification({
      title: "Success",
      message: "Semua file berhasil dihapus",
      color: "green",
    });

    mutate();
    setAudioUrl(null);
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <Card shadow="sm" radius="md" padding="lg">
      <Stack gap="md">
        <Group justify="space-between">
          <Title order={4}>List Audio</Title>

          <Button color="red" size="xs" variant="outline" onClick={deleteAll}>
            Hapus Semua
          </Button>
        </Group>

        {(data?.data?.data || []).map((audio) => (
          <Group justify="space-between" key={audio}>
            {audio}
            <Group gap={8}>
              <Button size="xs" onClick={() => playAudio(audio)}>
                Play
              </Button>

              <Button
                size="xs"
                variant="light"
                onClick={() => downloadAudio(audio)}
              >
                Download
              </Button>

              <Button
                size="xs"
                color="red"
                variant="outline"
                onClick={() => deleteAudio(audio)}
              >
                Delete
              </Button>
            </Group>
          </Group>
        ))}

        {audioUrl && (
          <audio
            src={audioUrl}
            controls
            autoPlay
            style={{ width: "100%", marginTop: 10 }}
          />
        )}
      </Stack>
    </Card>
  );
}
