/**
 * Map layers control (Explore) — toggles for 3D buildings, POIs, and the
 * light/dark map theme, plus the online/offline source. A bottom sheet
 * opened from the Layers FAB.
 */
import React from "react";
import { StyleSheet, Switch, Text, View } from "react-native";
import { SegmentedControl } from "../../components";
import { radius, spacing, theme, typeScale } from "../../theme";
import type { MapTheme } from "../../state/types";

export type LayersSheetProps = {
  visible: boolean;
  onClose: () => void;
  show3dBuildings: boolean;
  showPois: boolean;
  mapTheme: MapTheme;
  mapSource: "online" | "offline";
  onChange: (
    patch: Partial<{
      show3dBuildings: boolean;
      showPois: boolean;
      mapTheme: MapTheme;
    }>
  ) => void;
  onMapSourceChange: (source: "online" | "offline") => void;
};

const THEME_OPTIONS: Array<{ value: MapTheme; label: string }> = [
  { value: "light", label: "Light" },
  { value: "dark", label: "Dark" },
];

const SOURCE_OPTIONS: Array<{ value: "online" | "offline"; label: string }> = [
  { value: "online", label: "Online" },
  { value: "offline", label: "Offline" },
];

function Row({
  label,
  value,
  onValueChange,
}: {
  label: string;
  value: boolean;
  onValueChange: (v: boolean) => void;
}): React.JSX.Element {
  return (
    <View style={styles.row}>
      <Text style={styles.rowLabel}>{label}</Text>
      <Switch
        value={value}
        onValueChange={onValueChange}
        trackColor={{ false: theme.border, true: theme.signal }}
        thumbColor={theme.surface}
      />
    </View>
  );
}

export function LayersSheet({
  visible,
  onClose,
  show3dBuildings,
  showPois,
  mapTheme,
  mapSource,
  onChange,
  onMapSourceChange,
}: LayersSheetProps): React.JSX.Element | null {
  if (!visible) return null;
  return (
    <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
      <View style={styles.scrim} onTouchEnd={onClose} />
      <View style={styles.sheet}>
        <View style={styles.handle} />
        <Text style={styles.title}>Map layers</Text>

        <Row
          label="3D buildings"
          value={show3dBuildings}
          onValueChange={(v) => onChange({ show3dBuildings: v })}
        />
        <Row
          label="Points of interest"
          value={showPois}
          onValueChange={(v) => onChange({ showPois: v })}
        />

        <View style={styles.segRow}>
          <Text style={styles.rowLabel}>Theme</Text>
          <SegmentedControl
            options={THEME_OPTIONS}
            value={mapTheme}
            onChange={(t) => onChange({ mapTheme: t })}
            testID="layers-theme"
          />
        </View>
        <View style={styles.segRow}>
          <Text style={styles.rowLabel}>Map source</Text>
          <SegmentedControl
            options={SOURCE_OPTIONS}
            value={mapSource}
            onChange={onMapSourceChange}
            testID="layers-source"
          />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  scrim: {
    ...StyleSheet.absoluteFill,
    backgroundColor: "rgba(16,24,42,0.28)",
  },
  sheet: {
    position: "absolute",
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: theme.surface,
    borderTopLeftRadius: radius.lg,
    borderTopRightRadius: radius.lg,
    paddingHorizontal: spacing[5],
    paddingTop: spacing[3],
    paddingBottom: spacing[10],
    gap: spacing[2],
  },
  handle: {
    alignSelf: "center",
    width: 40,
    height: 4,
    borderRadius: 2,
    backgroundColor: theme.border,
    marginBottom: spacing[3],
  },
  title: {
    ...typeScale.title,
    color: theme.textPrimary,
    marginBottom: spacing[2],
  },
  row: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingVertical: spacing[2],
  },
  segRow: {
    // Column layout — label above a full-width control, matching
    // SettingsScreen's `unitsRow`. A row layout with the label beside the
    // control let the control's natural width overflow the sheet and get
    // clipped at the screen edge; stacking keeps it within bounds since
    // SegmentedControl already flexes its segments to fill the parent.
    flexDirection: "column",
    alignItems: "stretch",
    paddingVertical: spacing[2],
    gap: spacing[2],
  },
  rowLabel: {
    ...typeScale.body,
    color: theme.textPrimary,
  },
});
