import { Ionicons } from "@expo/vector-icons";
import { useEffect, useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";

import { Input } from "@/components/ui/Input";
import { fonts, spacing } from "@/constants/theme";
import { useAccounts } from "@/contexts/AccountsContext";
import { useAppTheme } from "@/contexts/ThemeContext";
import { hasConfiguredInstanceUrl } from "@/lib/accounts";
import { OFFICIAL_SERVER_PLACEHOLDER } from "@/lib/config";

type CollapsibleServerFieldProps = {
  defaultExpanded?: boolean;
};

function formatServerLabel(url: string) {
  try {
    return new URL(url).host;
  } catch {
    return url.replace(/^https?:\/\//, "");
  }
}

export function CollapsibleServerField({ defaultExpanded = false }: CollapsibleServerFieldProps) {
  const { colors } = useAppTheme();
  const insets = useSafeAreaInsets();
  const { apiUrl, setInstanceUrl } = useAccounts();
  const [expanded, setExpanded] = useState(defaultExpanded);
  const [value, setValue] = useState(apiUrl);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    hasConfiguredInstanceUrl().then((configured) => {
      if (!configured) setExpanded(true);
    });
  }, []);

  useEffect(() => {
    setValue(apiUrl);
  }, [apiUrl]);

  async function commit() {
    const trimmed = value.trim();
    if (!trimmed || trimmed === apiUrl) {
      setError(null);
      setExpanded(false);
      return;
    }

    try {
      const saved = await setInstanceUrl(trimmed);
      setValue(saved);
      setError(null);
      setExpanded(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Could not save server URL");
    }
  }

  return (
    <View
      style={[
        styles.wrapper,
        { paddingBottom: Math.max(insets.bottom, spacing.sm) },
      ]}
    >
      <Pressable
        accessibilityRole="button"
        accessibilityState={{ expanded }}
        onPress={() => setExpanded((open) => !open)}
        hitSlop={8}
        style={({ pressed }) => [styles.trigger, pressed && styles.pressed]}
      >
        <Text style={[styles.triggerText, { color: colors.mutedForeground }]}>
          Server ·{" "}
          <Text style={[styles.host, { color: colors.foreground }]}>
            {formatServerLabel(apiUrl)}
          </Text>
        </Text>
        <Ionicons
          name={expanded ? "chevron-down" : "chevron-up"}
          size={16}
          color={colors.mutedForeground}
        />
      </Pressable>

      {expanded ? (
        <View
          style={[
            styles.panel,
            { backgroundColor: colors.cardGlass, borderColor: colors.borderGlass },
          ]}
        >
          <Input
            label="Server instance"
            value={value}
            onChangeText={setValue}
            onBlur={commit}
            onSubmitEditing={commit}
            autoCapitalize="none"
            autoCorrect={false}
            keyboardType="url"
            placeholder={OFFICIAL_SERVER_PLACEHOLDER}
            error={error ?? undefined}
          />
          <Text style={[styles.hint, { color: colors.mutedForeground }]}>
            Use your Mac&apos;s LAN IP on a physical device.
          </Text>
        </View>
      ) : null}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flexDirection: "column-reverse",
    gap: spacing.sm,
    paddingHorizontal: spacing.md,
  },
  trigger: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    gap: spacing.xs,
    minHeight: 36,
  },
  pressed: {
    opacity: 0.7,
  },
  triggerText: {
    fontSize: 13,
    fontFamily: fonts.body,
  },
  host: {
    fontFamily: fonts.mono,
    fontSize: 13,
  },
  panel: {
    borderWidth: 1,
    borderRadius: 14,
    padding: spacing.md,
    gap: spacing.sm,
  },
  hint: {
    fontSize: 12,
    fontFamily: fonts.body,
    lineHeight: 16,
  },
});
