import React, { useState, useEffect } from "react";
import { View, Text, TextInput, Pressable, StyleSheet } from "react-native";
import {
  WhisperFile,
  download_status_t,
  whisper_tag_t,
} from "@/app/lib/whisper";
import { Settings } from "@/app/lib/settings";
import { Picker } from "@react-native-picker/picker";
import {
  LanguageServer,
  language_matrix,
  language_matrix_entry,
} from "@/app/i18n/api";
const WHISPER_MODELS = {
  small: new WhisperFile("small"),
  medium: new WhisperFile("medium"),
  large: new WhisperFile("large"),
};

const LIBRETRANSLATE_BASE_URL = "https://translate.argosopentech.com/translate";

const SettingsComponent = () => {
  const [hostLanguage, setHostLanguage] = useState<string | null>(null);
  const [libretranslateBaseUrl, setLibretranslateBaseUrl] = useState<
    string | null
  >(null);
  const [languageOptions, setLanguageOptions] = useState<
    language_matrix | undefined
  >();
  const [langServerConn, setLangServerConn] = useState<{
    success: boolean;
    error?: string;
  } | null>(null);
  const [whisperModel, setWhisperModel] =
    useState<keyof typeof WHISPER_MODELS>("small");
  const [downloader, setDownloader] = useState<any>(null);
  const [whisperFile, setWhisperFile] = useState<WhisperFile | undefined>();
  const [downloadStatus, setDownloadStatus] = useState<
    undefined | download_status_t
  >();
  const [statusTimeout, setStatusTimeout] = useState<
    NodeJS.Timeout | undefined
  >();

  useEffect(() => {
    loadSettings();
  }, []);

  const getLanguageOptions = async () => {
    const languageServer = await LanguageServer.getDefault();
    setLanguageOptions(await languageServer.fetchLanguages());
  };

  const loadSettings = async () => {
    const settings = await Settings.getDefault();
    setHostLanguage((await settings.getHostLanguage()) || "en");
    setLibretranslateBaseUrl(
      (await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL
    );
    setWhisperModel(await settings.getWhisperModel());
  };

  const handleHostLanguageChange = async (lang: string) => {
    const settings = await Settings.getDefault();
    setHostLanguage(lang);
    await settings.setHostLanguage(lang);
  };

  const handleLibretranslateBaseUrlChange = async (url: string) => {
    const settings = await Settings.getDefault();
    setLibretranslateBaseUrl(url);
    await settings.setLibretranslateBaseUrl(url);
    checkLangServerConnection(url);
  };

  const checkLangServerConnection = async (baseUrl: string) => {
    try {
      // Replace with actual connection check logic
      setLangServerConn({ success: true });
    } catch (error) {
      setLangServerConn({ success: false, error: `${error}` });
    }
  };

  const intervalUpdateDownloadStatus = async () => {
    if (!whisperFile) return;
    const status = await whisperFile.getDownloadStatus();
    setDownloadStatus(status);
  };

  const handleWhisperModelChange = async (model: whisper_tag_t) => {
    const settings = await Settings.getDefault();
    await settings.setWhisperModel(model);
    setWhisperModel(model);
    setWhisperFile(new WhisperFile(model));
  };

  const doDownload = async () => {
    if (!whisperModel) {
      throw new Error("Could not start download because whisperModel not set.");
    }

    console.log("Starging download of %s", whisperModel)

    const whisperFile = new WhisperFile(whisperModel);

    const resumable = await whisperFile.createDownloadResumable();
    setDownloader(resumable);
    try {
      await resumable.downloadAsync();
      const statusTimeout = setInterval(intervalUpdateDownloadStatus, 200);
      setStatusTimeout(statusTimeout);
    } catch (error) {
      console.error("Failed to download whisper model:", error);
    }
  };

  const doStopDownload = async () => {
    downloader.cancelAsync();
    setDownloader(null);
  };

  const doDelete = async () => {
    const whisperFile = WHISPER_MODELS[whisperModel];
    whisperFile.delete();
    setStatusTimeout(undefined);
  };

  return hostLanguage && libretranslateBaseUrl ? (
    <View style={styles.container}>
      <Text style={styles.label}>Host Language:</Text>
      {
        <Picker
          selectedValue={hostLanguage}
          style={{ height: 50, width: "100%" }}
          onValueChange={handleHostLanguageChange}
          accessibilityHint="host language"
        >
          {languageOptions &&
            Object.entries(languageOptions).map(([key, value]) => {
              return <Picker.Item label={value.name} value={value.code} />;
            })}
        </Picker>
      }

      <Text style={styles.label}>LibreTranslate Base URL:</Text>
      <TextInput
        style={styles.input}
        value={libretranslateBaseUrl || LIBRETRANSLATE_BASE_URL}
        onChangeText={handleLibretranslateBaseUrlChange}
        accessibilityHint="libretranslate base url"
      />
      {langServerConn &&
        (langServerConn.success ? (
          <Text>Success connecting to {libretranslateBaseUrl}</Text>
        ) : (
          <Text>
            Error connecting to {libretranslateBaseUrl}: {langServerConn.error}
          </Text>
        ))}
      <Picker
        selectedValue={whisperModel}
        style={{ height: 50, width: "100%" }}
        onValueChange={handleWhisperModelChange}
        accessibilityHint="whisper models"
      >
        {Object.entries(WHISPER_MODELS).map(([key, whisperFile]) => (
          <Picker.Item
            key={whisperFile.tag}
            label={whisperFile.label}
            value={key}
          />
        ))}
      </Picker>
      <View>
        {whisperModel &&
          (downloadStatus?.isDownloadComplete ? (
            downloadStatus?.doesTargetExist ? (
              <Pressable onPress={doDelete}>
                <Text>DELETE {whisperModel.toUpperCase()}</Text>
              </Pressable>
            ) : (
              <Pressable onPress={doStopDownload}>
                <Text>PAUSE</Text>
              </Pressable>
            )
          ) : (
            <Pressable onPress={doDownload}>
              <Text>DOWNLOAD {whisperModel.toUpperCase()}</Text>
            </Pressable>
          ))}
        {downloadStatus?.progress && (
          <View>
            <Text>
              {downloadStatus.progress.current} of{" "}
              {downloadStatus.progress.total} (
              {downloadStatus.progress.percentRemaining} %){" "}
            </Text>
          </View>
        )}
      </View>
    </View>
  ) : (
    <View>
      <Text>Loading ...</Text>
    </View>
  );
};

// Create styles for the component
const styles = StyleSheet.create({
  downloadButtonWrapper: {
    flexDirection: "row",
  },
  downloadButton: {
    backgroundColor: "darkblue",
    padding: 20,
    margin: 10,
    flex: 3,
    flexDirection: "column",
  },
  deleteButton: {
    backgroundColor: "darkred",
    flex: 1,
    flexDirection: "column",
    padding: 10,
    margin: 10,
    height: 50,
  },
  pauseDownloadButton: {
    backgroundColor: "#444444",
    padding: 10,
    margin: 10,
    height: 50,
  },
  buttonText: {
    color: "#fff",
    flex: 1,
    fontSize: 16,
    alignSelf: "center",
    textAlign: "center",
    textAlignVertical: "top",
  },
  container: {
    flex: 1,
    padding: 20,
  },
  label: {
    fontSize: 16,
    marginBottom: 8,
  },
  input: {
    height: 40,
    borderColor: "gray",
    borderWidth: 1,
    marginBottom: 20,
    paddingHorizontal: 8,
  },
});

export default SettingsComponent;
