import { MaterialCommunityIcons } from "@expo/vector-icons";
import { useFocusEffect } from "expo-router";
import {
  Alert,
  Linking,
  Platform,
  ScrollView,
  Text,
  View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Children, Fragment, useCallback, useState } from "react";

import { SettingsRow } from "@/components/settings-row";
import {
  type Lang,
  type ThemeMode,
  useSettingsStore,
} from "@/lib/settings";
import { useT } from "@/lib/i18n";
import { useLocationPermission } from "@/lib/use-location-permission";

type IconName = React.ComponentProps<typeof MaterialCommunityIcons>["name"];

const SectionHeader = ({ title }: { title: string }) => (
  <Text className="text-xs font-JakartaSemiBold uppercase tracking-wide text-general-200 dark:text-neutral-500 mt-6 mb-2 px-1">
    {title}
  </Text>
);

/**
 * A grouped settings card. Renders an optional muted description header, then
 * its children with an automatic divider between each row — so callers never
 * hand-thread `border-t` wrapper Views. Null/conditional children (and arrays
 * from `.map`) are flattened by `Children.toArray`, so conditionals like
 * `status !== "granted" ? <Row/> : null` and `options.map(...)` both work.
 */
const SettingsCard = ({
  description,
  children,
}: {
  description?: string;
  children: React.ReactNode;
}) => {
  const rows = Children.toArray(children);

  return (
    <View className="rounded-2xl bg-white dark:bg-neutral-900 overflow-hidden shadow-sm shadow-neutral-300 dark:shadow-neutral-950/40">
      {description ? (
        <View className="px-4 py-2.5">
          <Text className="text-xs font-Jakarta text-general-200 dark:text-neutral-400">
            {description}
          </Text>
        </View>
      ) : null}
      {rows.map((row, index) => (
        <Fragment key={index}>
          {index > 0 ? (
            <View className="border-t border-neutral-100 dark:border-neutral-800" />
          ) : null}
          {row}
        </Fragment>
      ))}
    </View>
  );
};

const Settings = () => {
  const t = useT();

  const mode = useSettingsStore((state) => state.mode);
  const setMode = useSettingsStore((state) => state.setMode);
  const lang = useSettingsStore((state) => state.lang);
  const setLang = useSettingsStore((state) => state.setLang);
  const keepAwake = useSettingsStore((state) => state.keepAwake);
  const setKeepAwake = useSettingsStore((state) => state.setKeepAwake);
  const overlayRequested = useSettingsStore(
    (state) => state.overlayRequested,
  );
  const setOverlayRequested = useSettingsStore(
    (state) => state.setOverlayRequested,
  );

  const { status, refresh, openSettings } = useLocationPermission();
  useFocusEffect(
    useCallback(() => {
      void refresh();
    }, [refresh]),
  );

  const [expandedSafety, setExpandedSafety] = useState<string | null>(null);

  const locationStatusLabel =
    status === "granted"
      ? t("settings.maps.statusGranted")
      : status === "denied"
        ? t("settings.maps.statusDenied")
        : status === "blocked"
          ? t("settings.maps.statusBlocked")
          : t("settings.maps.statusUnknown");

  const callEmergency = useCallback(async () => {
    try {
      await Linking.openURL("tel:112");
    } catch {
      Alert.alert(
        t("settings.safety.callFailedTitle"),
        t("settings.safety.callFailedBody"),
      );
    }
  }, [t]);

  const chooseLanguage = useCallback(
    (next: Lang) => {
      const switchingToOrFromRTL = next === "ar" || lang === "ar";

      setLang(next);

      if (switchingToOrFromRTL) {
        Alert.alert(
          t("settings.language.rtlRestartTitle"),
          t("settings.language.rtlRestartBody"),
        );
      }
    },
    [lang, setLang, t],
  );

  const openOverlaySettings = useCallback(async () => {
    setOverlayRequested(true);
    try {
      await Linking.openSettings();
    } catch {
      // already flagged; nothing more to do
    }
  }, [setOverlayRequested]);

  const appearanceOptions: { mode: ThemeMode; icon: IconName }[] = [
    { mode: "light", icon: "white-balance-sunny" },
    { mode: "dark", icon: "weather-night" },
    { mode: "system", icon: "theme-light-dark" },
  ];

  const languageOptions: { lang: Lang; icon: IconName }[] = [
    { lang: "en", icon: "alpha-e-box" },
    { lang: "ar", icon: "alpha-a-box" },
    { lang: "fr", icon: "alpha-f-box" },
  ];

  const safetyTiles: { key: string; icon: IconName; title: string; body: string }[] = [
    {
      key: "proactive",
      icon: "shield-account",
      title: t("settings.safety.proactive.title"),
      body: t("settings.safety.proactive.body"),
    },
    {
      key: "verification",
      icon: "account-check",
      title: t("settings.safety.verification.title"),
      body: t("settings.safety.verification.body"),
    },
    {
      key: "privacy",
      icon: "lock",
      title: t("settings.safety.privacy.title"),
      body: t("settings.safety.privacy.body"),
    },
  ];

  return (
    <SafeAreaView className="flex-1 bg-general-500 dark:bg-neutral-950">
      <ScrollView
        className="px-5"
        contentContainerStyle={{ paddingBottom: 120 }}
      >
        <Text className="text-2xl font-JakartaBold my-5 text-black dark:text-white">
          {t("settings.title")}
        </Text>

        {/* 1. Maps & Navigation */}
        <SectionHeader title={t("settings.maps.title")} />
        <SettingsCard>
          <SettingsRow
            icon="map-marker-radius"
            title={t("settings.maps.title")}
            subtitle={t("settings.maps.description")}
            right="value"
            value={locationStatusLabel}
          />
          {status !== "granted" ? (
            <SettingsRow
              icon="cog"
              title={t("settings.maps.openSettings")}
              right="chevron"
              onPress={openSettings}
            />
          ) : null}
        </SettingsCard>

        {/* 2. Appearance */}
        <SectionHeader title={t("settings.appearance.title")} />
        <SettingsCard description={t("settings.appearance.description")}>
          {appearanceOptions.map((option) => (
            <SettingsRow
              key={option.mode}
              icon={option.icon}
              title={
                option.mode === "light"
                  ? t("settings.appearance.light")
                  : option.mode === "dark"
                    ? t("settings.appearance.dark")
                    : t("settings.appearance.system")
              }
              right="check"
              selected={mode === option.mode}
              onPress={() => setMode(option.mode)}
            />
          ))}
        </SettingsCard>

        {/* 3. Safety */}
        <SectionHeader title={t("settings.safety.title")} />
        <SettingsCard>
          <SettingsRow
            icon="phone-in-talk"
            title={t("settings.safety.call112")}
            subtitle={t("settings.safety.call112Description")}
            right="chevron"
            danger
            onPress={callEmergency}
          />
          {safetyTiles.map((tile) => (
            <SettingsRow
              key={tile.key}
              icon={tile.icon}
              title={tile.title}
              subtitle={expandedSafety === tile.key ? undefined : tile.body}
              right="chevron"
              onPress={() =>
                setExpandedSafety((current) =>
                  current === tile.key ? null : tile.key,
                )
              }
            />
          ))}
        </SettingsCard>

        {/* 4. Language */}
        <SectionHeader title={t("settings.language.title")} />
        <SettingsCard description={t("settings.language.description")}>
          {languageOptions.map((option) => (
            <SettingsRow
              key={option.lang}
              icon={option.icon}
              title={
                option.lang === "en"
                  ? t("settings.language.en")
                  : option.lang === "ar"
                    ? t("settings.language.ar")
                    : t("settings.language.fr")
              }
              right="check"
              selected={lang === option.lang}
              onPress={() => chooseLanguage(option.lang)}
            />
          ))}
        </SettingsCard>

        {/* 5. General — keep-awake toggle + (Android) display-over-other-apps */}
        <SectionHeader title={t("settings.general.title")} />
        <SettingsCard>
          <SettingsRow
            icon="monitor"
            title={t("settings.keepAwake.title")}
            subtitle={t("settings.keepAwake.description")}
            right="switch"
            switchValue={keepAwake}
            onSwitchChange={setKeepAwake}
          />
          {Platform.OS === "android" ? (
            <SettingsRow
              icon="application-brackets"
              title={t("settings.overlay.allow")}
              subtitle={
                overlayRequested
                  ? t("settings.overlay.openedHint")
                  : t("settings.overlay.description")
              }
              right="chevron"
              onPress={openOverlaySettings}
            />
          ) : null}
        </SettingsCard>
      </ScrollView>
    </SafeAreaView>
  );
};

export default Settings;