import * as React from 'react';
import {
  createContext,
  forwardRef,
  useCallback,
  useContext,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import { StyleSheet, View } from 'react-native';
import type { NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle } from 'react-native';
import NativeSMapView, { Commands } from './SMapNativeViewNativeComponent';
import { cameraJson, toFeatureCollection, toLatLng, type GeoJSONFeatureCollection, type LayerData, type LngLatLike } from './geojson';
import {
  encodeInput,
  type ArcGisLayerOptions,
  type BasemapOverrides,
  type CustomStyle,
  type DataFormat,
  type DataInput,
  type LayerDescription,
  type RasterLayerOptions,
  type ReadOptions,
  type Slot,
  type StyleLayerSpec,
  type StyleSource,
  type VectorTilesOptions,
  type WmsLayerOptions,
  type WmtsLayerOptions,
} from './types';
import { ToolsLayer, hiddenOf, toolsOf, usesMiles, type Camera, type ToolState, type ToolsChangeEvent, type ToolsOptions } from './tools';

export type StyleFlavor = 'light' | 'white' | 'grayscale' | 'dark' | 'black';
export const styles: StyleFlavor[] = ['light', 'white', 'grayscale', 'dark', 'black'];

export type LayerKind = 'points' | 'lines' | 'polygons';

/** Called with the tapped feature's properties and its position. */
export type TapHandler = (properties: Record<string, unknown>, position: { lat: number; lng: number }) => void;

/** The map, as the ref of `<SMap>` and `useSMap()` give it once it is ready. */
export interface SMapHandle {
  addPoints(id: string, data: LayerData, options?: Record<string, unknown>): void;
  addLines(id: string, data: LayerData, options?: Record<string, unknown>): void;
  addPolygons(id: string, data: LayerData, options?: Record<string, unknown>): void;
  /** Replaces a layer's data and keeps its look. */
  setData(id: string, data: LayerData): void;
  setVisible(id: string, visible: boolean): void;
  removeLayer(id: string): void;
  /** Layer ids in draw order, bottom first. */
  layers(): string[];
  /** Moves the camera to show a layer's data; padding in points (40), maxZoom 15. */
  fitLayer(id: string, options?: { padding?: number; maxZoom?: number }): void;
  flyTo(center: LngLatLike, zoom?: number): void;
  /** Calls `handler` when a feature of layer `id` is tapped (null removes it). */
  onTap(id: string, handler: TapHandler | null): void;
  setStyle(style: StyleFlavor | CustomStyle): void;
  setLanguage(language: string): void;
  setBuildings3D(on: boolean): void;

  // 1.1.0. Calls without a result resolve when the native map has done them (a failure goes to onError);
  // calls with a result reject on a failure.

  /** Adds a Style Specification v8 source, passed through unchanged. */
  addSource(id: string, source: StyleSource): Promise<void>;
  removeSource(id: string): Promise<void>;
  /** Adds a Style Specification v8 layer, under `before` or in `slot` (on top without either). */
  addStyleLayer(layer: StyleLayerSpec, options?: { before?: string; slot?: Slot }): Promise<void>;
  setPaint(layerId: string, name: string, value: unknown): Promise<void>;
  setLayout(layerId: string, name: string, value: unknown): Promise<void>;
  setFilter(layerId: string, filter: unknown): Promise<void>;
  /** The style layer as the map holds it, or null. */
  getStyleLayer(layerId: string): Promise<StyleLayerSpec | null>;
  /** Replaces the basemap overrides (`{}` clears them); kept across style and language changes. */
  setBasemap(overrides: BasemapOverrides): Promise<void>;
  /** The current basemap overrides. */
  basemap(): Promise<BasemapOverrides>;
  /**
   * Reads a file (KML, KMZ, GPX, polyline, WKT, WKB, CSV, TopoJSON, GeoJSON) with the native readers and draws its
   * points as `<id>`, lines as `<id>:lines` and areas as `<id>:areas`. Resolves with the layer ids made.
   */
  addData(id: string, input: DataInput, options?: ReadOptions & Record<string, unknown>): Promise<string[]>;
  /** A layer's features as GeoJSON. */
  toGeoJSON(layerId: string): Promise<GeoJSONFeatureCollection>;
  /** A layer's features as KML text. */
  toKML(layerId: string): Promise<string>;
  /** Converts a file on the map service (`POST /v1/convert`), for large files. */
  convert(input: DataInput, options: { format: DataFormat; lat?: string; lng?: string }): Promise<GeoJSONFeatureCollection>;
  addRasterLayer(id: string, options: RasterLayerOptions): Promise<void>;
  addWmsLayer(id: string, options: WmsLayerOptions): Promise<void>;
  addWmtsLayer(id: string, options: WmtsLayerOptions): Promise<void>;
  addVectorTiles(id: string, options: VectorTilesOptions): Promise<void>;
  addArcGisLayer(id: string, options: ArcGisLayerOptions): Promise<void>;
  /** The map's layers as the description every sMap SDK reads. */
  toJSON(): Promise<LayerDescription>;
  /** Loads a layer description (an id already on the map is replaced). */
  loadLayers(json: LayerDescription | string): Promise<void>;
  /** A `{z}/{x}/{y}` raster tile URL template of a scheme or `custom:<id>` on the map's node. */
  rasterUrl(style: string, options?: { lang?: string; retina?: boolean }): Promise<string>;
  /** Shows a downloaded offline region instead of the map service; false when it is not on the device or expired. */
  useOfflineRegion(id: string): Promise<boolean>;
  /** Reads the map service again after `useOfflineRegion` (or a fallback to a region). */
  useOnline(): Promise<void>;
  /** The offline region shown now; null while the map reads the map service. */
  offlineRegionInUse(): Promise<string | null>;

  // Map tools (the `<Tool>` children).

  /** Shows or hides one tool. A hidden tool stays mounted and keeps its state. */
  setToolVisible(id: string, visible: boolean): void;
  /** Shows or hides every tool. The attribution and the sMap badge always stay. */
  setToolsVisible(visible: boolean): void;
  /** The tools in the order given. */
  tools(): ToolState[];
}

const MapContext = createContext<SMapHandle | null>(null);

/** The map of the nearest `<SMap>` above, once it is ready (null before). */
export function useSMap(): SMapHandle | null {
  return useContext(MapContext);
}

export interface SMapProps extends Omit<ViewProps, 'style'> {
  /** A map key (`smk_…`) whose allowlist names this app. Read when the map is created. */
  apiKey?: string;
  /** A map token. Read when the map is created; changing it creates the map again (use `getToken` to renew). */
  token?: string;
  /** Called at start when no token is given and again two minutes before each token expires. */
  getToken?: () => string | Promise<string>;
  /**
   * The colour scheme or a saved custom style (`custom:sms_…`); layers and basemap overrides are kept on a change. A
   * style object here is taken as `containerStyle`.
   */
  style?: StyleFlavor | CustomStyle | StyleProp<ViewStyle>;
  /**
   * Basemap overrides by class (`{ water: { color: '#9cc0e6' }, pois: { visible: false } }`); a new value replaces
   * the previous overrides, removing the prop clears them.
   */
  basemap?: BasemapOverrides;
  /** Label language (`en`, `fr`, `zh-Hans`, …); the device language by default. Layers are kept on a change. */
  language?: string;
  /** [longitude, latitude] or `{lng, lat}`; the camera follows a change. */
  center?: LngLatLike;
  zoom?: number;
  bearing?: number;
  pitch?: number;
  /** Node URLs known in advance, used while `baseUrl` is down. */
  nodes?: string[];
  /** The map service, `https://tile.srsr.ca` by default. */
  baseUrl?: string;
  /** Read from the nearest service node (default true). */
  nearest?: boolean;
  /** Buildings in 3D. */
  buildings3D?: boolean;
  /** Show this downloaded offline region from the start, without the network (see `offlineRegions`). */
  offlineRegion?: string;
  /** When the map service cannot be reached, show a downloaded region containing the centre (default true). */
  offlineFallback?: boolean;
  /** While online, download again the regions in their last 3 days (default true; billed as a download). */
  offlineAutoRefresh?: boolean;
  /** Called once the first style has loaded. */
  onReady?: (map: SMapHandle) => void;
  /** Errors from the map (a failed token, a style that could not load). */
  onError?: (error: Error) => void;
  /**
   * Map tools: the ids hidden from the start, where the tools control sits (or false for none) and its labels. Read
   * when the map is created; give the tools as `<Tool>` children.
   */
  tools?: ToolsOptions;
  /** Called after every change of the tools' visibility; the map keeps no state itself. */
  onToolsChange?: (event: ToolsChangeEvent) => void;
  /** The layout of the map view. */
  containerStyle?: StyleProp<ViewStyle>;
  children?: React.ReactNode;
}

type NativeRef = React.ElementRef<typeof NativeSMapView>;

/**
 * A map view. The ref is the map (`SMapHandle`) once the first style has loaded, null before.
 */
export const SMap = forwardRef<SMapHandle | null, SMapProps>(function SMap(props, ref) {
  const {
    apiKey, token, getToken, style, language, center, zoom, bearing, pitch, nodes, baseUrl, nearest, buildings3D, basemap,
    offlineRegion, offlineFallback, offlineAutoRefresh, onReady, onError, containerStyle, children, tools: toolsOptions,
    onToolsChange, ...viewProps
  } = props;
  // The <Tool> children are laid out by the tools layer; every other child is drawn as before.
  const { tools: toolList, rest } = toolsOf(children);
  const [hiddenTools, setHiddenTools] = useState<Set<string>>(() => new Set(toolsOptions?.hidden || []));
  const [panelOpen, setPanelOpen] = useState(false);
  const [cameraNow, setCameraNow] = useState<Camera | null>(null);
  const toolsRef = useRef(toolList);
  toolsRef.current = toolList;
  const hiddenRef = useRef(hiddenTools);
  hiddenRef.current = hiddenTools;
  const toolsOptionsRef = useRef(toolsOptions);
  const switchTools = useCallback((ids: string[], visible: boolean, changed: string | null) => {
    const now = hiddenRef.current;
    const flip = ids.filter((id) => toolsRef.current.some((t) => t.id === id) && now.has(id) === visible);
    if (flip.length === 0) { return; }
    const next = new Set(now);
    flip.forEach((id) => { if (visible) { next.delete(id); } else { next.add(id); } });
    hiddenRef.current = next;
    setHiddenTools(next);
    latest.current.onToolsChange?.({ hidden: hiddenOf(toolsRef.current, next), changed });
  }, []);
  const flavorProp = typeof style === 'string' ? style : undefined;
  const layoutStyle = typeof style === 'string' ? containerStyle : [containerStyle, style as StyleProp<ViewStyle>];

  const native = useRef<NativeRef | null>(null);
  const latest = useRef(props);
  latest.current = props;
  const [handle, setHandle] = useState<SMapHandle | null>(null);
  const [flavor, setFlavor] = useState<string>(flavorProp || 'light');
  const [lang, setLang] = useState<string>(language || '');
  const [buildings, setBuildings] = useState<boolean>(!!buildings3D);
  useEffect(() => { if (flavorProp) { setFlavor(flavorProp); } }, [flavorProp]);
  useEffect(() => { if (language !== undefined) { setLang(language); } }, [language]);
  useEffect(() => { setBuildings(!!buildings3D); }, [buildings3D]);

  // Read when the native map is created; a change creates it again (the native view gets a new key).
  const config = JSON.stringify({
    baseUrl: baseUrl || null,
    nodes: nodes || [],
    apiKey: apiKey || null,
    token: token || null,
    nearest: nearest !== false,
    getToken: !!getToken,
    offlineRegion: offlineRegion || null,
    offlineFallback: offlineFallback !== false,
    offlineAutoRefresh: offlineAutoRefresh !== false,
  });
  const camera = cameraJson({ center, zoom, bearing, pitch });
  const basemapJson = basemap ? JSON.stringify(basemap) : '';

  // The layers of this map, in the order the native SDKs keep them (zIndex, then the order added).
  const layers = useRef<{ id: string; zIndex: number }[]>([]);
  const taps = useRef<Record<string, TapHandler>>({});
  // Calls waiting for onCallResult.
  const pending = useRef(new Map<number, { resolve: (v: unknown) => void; reject: (e: Error) => void }>());
  const nextCall = useRef(0);
  // A handle works only for the native view it was made for; a new view (new config) makes the old handle inert.
  const generation = useRef(0);
  useEffect(() => {
    generation.current += 1;
    layers.current = [];
    taps.current = {};
    pending.current.forEach((p) => p.reject(new Error('sMap: the map was created again')));
    pending.current.clear();
    setHandle(null);
  }, [config]);

  const makeHandle = useCallback((): SMapHandle => {
    const mine = generation.current;
    const live = () => generation.current === mine && native.current !== null;
    const view = () => native.current as NativeRef;
    const track = (id: string, zIndex: number) => {
      const rest = layers.current.filter((l) => l.id !== id);
      rest.push({ id, zIndex });
      // A stable sort: equal zIndex keeps the order added.
      layers.current = rest.map((l, i) => ({ l, i })).sort((a, b) => a.l.zIndex - b.l.zIndex || a.i - b.i).map((x) => x.l);
    };
    const untrack = (id: string) => {
      layers.current = layers.current.filter((l) => l.id !== id);
      delete taps.current[id];
    };
    // One `call` command; resolves with the parsed result.
    const call = (method: string, args: unknown[]): Promise<unknown> => {
      if (!live()) { return Promise.reject(new Error('sMap: the map is gone')); }
      const requestId = ++nextCall.current;
      return new Promise((resolve, reject) => {
        pending.current.set(requestId, { resolve, reject });
        Commands.call(view(), requestId, method, JSON.stringify(args));
      });
    };
    // A call without a result: a failure goes to onError, a gone map is no failure.
    const run = (method: string, args: unknown[]): Promise<void> => {
      if (!live()) { return Promise.resolve(); }
      return call(method, args).then(() => undefined, (e: Error) => { latest.current.onError?.(e); });
    };
    const addExternal = (method: string) => (id: string, options: object) => {
      if (live()) { track(id, 0); }
      return run(method, [id, options]);
    };
    const add = (kind: LayerKind, id: string, data: LayerData, options: Record<string, unknown> = {}) => {
      if (!live()) { return; }
      track(id, typeof options.zIndex === 'number' ? options.zIndex : 0);
      Commands.addLayer(view(), kind, id, JSON.stringify(toFeatureCollection(data)), JSON.stringify(options));
    };
    return {
      addPoints: (id, data, options) => add('points', id, data, options),
      addLines: (id, data, options) => add('lines', id, data, options),
      addPolygons: (id, data, options) => add('polygons', id, data, options),
      setData: (id, data) => { if (live()) { Commands.setData(view(), id, JSON.stringify(toFeatureCollection(data))); } },
      setVisible: (id, visible) => { if (live()) { Commands.setVisible(view(), id, visible); } },
      removeLayer: (id) => {
        if (!live()) { return; }
        untrack(id);
        Commands.removeLayer(view(), id);
      },
      layers: () => (live() ? layers.current.map((l) => l.id) : []),
      fitLayer: (id, options = {}) => { if (live()) { Commands.fitLayer(view(), id, options.padding ?? 40, options.maxZoom ?? 15); } },
      flyTo: (c, z) => {
        if (!live()) { return; }
        const p = toLatLng(c);
        Commands.flyTo(view(), p.lat, p.lng, typeof z === 'number' ? z : -1);
      },
      onTap: (id, handler) => {
        if (!live()) { return; }
        if (handler) { taps.current[id] = handler; } else { delete taps.current[id]; }
      },
      setStyle: (s) => setFlavor(s),
      setLanguage: (l) => setLang(l),
      setBuildings3D: (on) => setBuildings(on),
      addSource: (id, source) => run('addSource', [id, source]),
      removeSource: (id) => run('removeSource', [id]),
      addStyleLayer: (layer, options = {}) => {
        if (live()) { track(layer.id, 0); }
        return run('addStyleLayer', [layer, options]);
      },
      setPaint: (layerId, name, value) => run('setPaint', [layerId, name, value === undefined ? null : value]),
      setLayout: (layerId, name, value) => run('setLayout', [layerId, name, value === undefined ? null : value]),
      setFilter: (layerId, filter) => run('setFilter', [layerId, filter === undefined ? null : filter]),
      getStyleLayer: (layerId) => call('getStyleLayer', [layerId]).then((r) => (r ?? null) as StyleLayerSpec | null),
      setBasemap: (overrides) => run('setBasemap', [overrides || {}]),
      basemap: () => call('basemap', []).then((r) => (r ?? {}) as BasemapOverrides),
      addData: (id, input, options = {}) => call('addData', [id, encodeInput(input), options]).then((r) => {
        const ids = Array.isArray(r) ? (r as string[]) : [];
        if (live()) { ids.forEach((l) => track(l, typeof options.zIndex === 'number' ? options.zIndex : 0)); }
        return ids;
      }),
      toGeoJSON: (layerId) => call('toGeoJSON', [layerId]) as Promise<GeoJSONFeatureCollection>,
      toKML: (layerId) => call('toKML', [layerId]).then((r) => String(r ?? '')),
      convert: (input, options) => call('convert', [encodeInput(input), options]) as Promise<GeoJSONFeatureCollection>,
      addRasterLayer: addExternal('addRasterLayer'),
      addWmsLayer: addExternal('addWmsLayer'),
      addWmtsLayer: addExternal('addWmtsLayer'),
      addVectorTiles: (id, options) => {
        if (live()) { (options.layers || []).forEach((l) => track(l.id, 0)); }
        return run('addVectorTiles', [id, options]);
      },
      addArcGisLayer: addExternal('addArcGisLayer'),
      toJSON: () => call('toJSON', []) as Promise<LayerDescription>,
      loadLayers: (json) => {
        const d: LayerDescription = typeof json === 'string' ? JSON.parse(json) : json;
        if (live()) { (d.layers || []).forEach((l) => track(l.id, typeof l.zIndex === 'number' ? l.zIndex : 0)); }
        return run('loadLayers', [d]);
      },
      rasterUrl: (s, options = {}) => call('rasterUrl', [s, options]).then((r) => String(r ?? '')),
      useOfflineRegion: (id) => call('useOfflineRegion', [id]).then((r) => r === true),
      useOnline: () => call('useOnline', []).then(() => undefined),
      offlineRegionInUse: () => call('offlineRegionInUse', []).then((r) => (typeof r === 'string' ? r : null)),
      setToolVisible: (id, visible) => switchTools([id], visible, id),
      setToolsVisible: (visible) => switchTools(toolsRef.current.map((t) => t.id), visible, null),
      tools: () => toolsRef.current.map((t) => ({ id: t.id, label: t.label, visible: !hiddenRef.current.has(t.id) })),
    };
  }, [switchTools]);

  useImperativeHandle(ref, () => handle as SMapHandle, [handle]);

  const handleReady = useCallback(() => {
    const h = makeHandle();
    setHandle(h);
    latest.current.onReady?.(h);
  }, [makeHandle]);

  const handleError = useCallback((e: NativeSyntheticEvent<{ message: string }>) => {
    latest.current.onError?.(new Error(e.nativeEvent.message));
  }, []);

  const handleTap = useCallback((e: NativeSyntheticEvent<{ layerId: string; properties: string; lat: number; lng: number }>) => {
    const { layerId, properties, lat, lng } = e.nativeEvent;
    const handler = taps.current[layerId];
    if (!handler) { return; }
    let parsed: Record<string, unknown> = {};
    try { parsed = JSON.parse(properties || '{}'); } catch { parsed = {}; }
    handler(parsed, { lat, lng });
  }, []);

  const handleCallResult = useCallback((e: NativeSyntheticEvent<{ requestId: number; result: string; error: string }>) => {
    const { requestId, result, error } = e.nativeEvent;
    const p = pending.current.get(requestId);
    if (!p) { return; }
    pending.current.delete(requestId);
    if (error) { p.reject(new Error(error)); return; }
    let value: unknown = null;
    try { value = result ? JSON.parse(result) : null; } catch { p.reject(new Error('sMap: unreadable answer')); return; }
    p.resolve(value);
  }, []);

  const handleTokenRequest = useCallback((e: NativeSyntheticEvent<{ requestId: number }>) => {
    const id = e.nativeEvent.requestId;
    const answer = (t: string, err: string) => { if (native.current) { Commands.resolveToken(native.current, id, t, err); } };
    const ask = latest.current.getToken;
    if (!ask) { answer('', 'sMap: no getToken'); return; }
    Promise.resolve()
      .then(() => ask())
      .then((t) => answer(String(t || ''), t ? '' : 'sMap: getToken gave no token'),
        (err: unknown) => answer('', 'sMap: ' + (err instanceof Error ? err.message : String(err))));
  }, []);

  const handleCamera = useCallback((e: NativeSyntheticEvent<Camera>) => {
    const { lat, lng, zoom: z, bearing: b } = e.nativeEvent;
    setCameraNow({ lat, lng, zoom: z, bearing: b });
  }, []);

  // Native calls of the tools; a gone map does nothing.
  const toolCall = useCallback((method: string, args: unknown[]): Promise<unknown> => {
    const view = native.current;
    if (!view) { return Promise.resolve(null); }
    const requestId = ++nextCall.current;
    return new Promise((resolve, reject) => {
      pending.current.set(requestId, { resolve, reject });
      Commands.call(view, requestId, method, JSON.stringify(args));
    });
  }, []);
  const toolActions = React.useMemo(() => ({
    zoomBy: (step: number) => { toolCall('zoomBy', [step]).catch((e: Error) => latest.current.onError?.(e)); },
    resetNorth: () => { toolCall('resetNorth', []).catch((e: Error) => latest.current.onError?.(e)); },
    locate: () => {
      toolCall('lastPosition', []).then((r) => {
        const answer = (r || {}) as { status?: string; lat?: number; lng?: number };
        if (answer.status === 'noPermission') { throw new Error('sMap: the app does not hold the location permission'); }
        if (answer.status !== 'ok' || typeof answer.lat !== 'number' || typeof answer.lng !== 'number') {
          throw new Error("sMap: the device's position is not known yet");
        }
        const view = native.current;
        if (view) { Commands.flyTo(view, answer.lat, answer.lng, Math.max(cameraNowRef.current?.zoom ?? 15, 15)); }
      }).catch((e: Error) => latest.current.onError?.(e));
    },
  }), [toolCall]);
  const cameraNowRef = useRef(cameraNow);
  cameraNowRef.current = cameraNow;

  // A compass tool takes the engine compass's place; the camera is sent only while a tool follows it.
  const hasCompass = toolList.some((t) => t.kind === 'compass');
  const followCamera = toolList.some((t) => t.kind === 'compass' || t.kind === 'scale' || t.kind === 'locate');
  // Sent only when it differs from what the native map does without tools (or from the last value sent), so a map
  // without tools gets no extra call.
  const sentCompass = useRef(false);
  const sentFollow = useRef(false);
  useEffect(() => { sentCompass.current = false; sentFollow.current = false; }, [handle]);
  useEffect(() => {
    if (!handle || hasCompass === sentCompass.current) { return; }
    sentCompass.current = hasCompass;
    toolCall('setEngineCompass', [!hasCompass]).catch(() => undefined);
  }, [handle, hasCompass, toolCall]);
  useEffect(() => {
    if (!handle || followCamera === sentFollow.current) { return; }
    sentFollow.current = followCamera;
    toolCall('followCamera', [followCamera]).catch(() => undefined);
  }, [handle, followCamera, toolCall]);
  const region = (() => {
    try { return Intl.DateTimeFormat().resolvedOptions().locale.split(/[-_]/)[1] || null; } catch { return null; }
  })();

  return (
    <View {...viewProps} style={[{ flex: 1 }, layoutStyle]}>
      <NativeSMapView
        key={config}
        ref={native}
        style={StyleSheet.absoluteFill}
        config={config}
        mapStyle={flavor}
        basemap={basemapJson}
        language={lang}
        camera={camera}
        buildings3D={buildings}
        onMapReady={handleReady}
        onMapError={handleError}
        onLayerTap={handleTap}
        onTokenRequest={handleTokenRequest}
        onCallResult={handleCallResult}
        onCameraChange={handleCamera}
        onTouchStart={panelOpen ? () => setPanelOpen(false) : undefined}
      />
      <MapContext.Provider value={handle}>{rest}</MapContext.Provider>
      {toolList.length > 0 ? (
        <ToolsLayer
          tools={toolList}
          hidden={hiddenTools}
          options={toolsOptionsRef.current || {}}
          camera={cameraNow}
          imperial={usesMiles(region)}
          actions={toolActions}
          open={panelOpen}
          setOpen={setPanelOpen}
          onToggle={(id) => switchTools([id], hiddenRef.current.has(id), id)}
          onAll={(visible) => switchTools(toolList.map((t) => t.id), visible, null)}
        />
      ) : null}
    </View>
  );
});
