import React, { useEffect, useRef, useState, useMemo } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Alert } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import { Map, Camera, GeoJSONSource, Layer, UserLocation } from '@maplibre/maplibre-react-native';
import type { LineLayerStyle } from '@maplibre/maplibre-react-native';
import { useRecordingStore } from '../store/recording';
import { startGpsRecording, stopGpsRecording, requestLocationPermissions } from '../services/gps';
import { RootStackParamList } from '../types';
import { colors } from '../theme';
import { useTheme } from '../ThemeContext';

const MAP_STYLE = 'https://tiles.openfreemap.org/styles/liberty';

type Nav = NativeStackNavigationProp<RootStackParamList>;

export function RecordingScreen() {
  const nav = useNavigation<Nav>();
  const { accent, accentDim, scale, boldLabels } = useTheme();
  const { status, ble, keepAwake, trackPoints, start, pause, resume, stop, setKeepAwake, getStats } = useRecordingStore();
  const [stats, setStats] = useState(getStats());
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  useEffect(() => {
    intervalRef.current = setInterval(() => setStats(getStats()), 1000);
    return () => { if (intervalRef.current) clearInterval(intervalRef.current); };
  }, []);

  useEffect(() => {
    if (keepAwake && status === 'recording') activateKeepAwakeAsync();
    else deactivateKeepAwake();
  }, [keepAwake, status]);

  const trackLineStyle = useMemo<LineLayerStyle>(() => ({
    lineColor: accent,
    lineWidth: 3,
    lineJoin: 'round',
    lineCap: 'round',
  }), [accent]);

  const trackGeoJSON = useMemo<GeoJSON.Feature<GeoJSON.LineString>>(() => ({
    type: 'Feature',
    geometry: { type: 'LineString', coordinates: trackPoints.map((p) => [p.lon, p.lat]) },
    properties: {},
  }), [trackPoints]);

  const statLabelStyle = useMemo(() => ({
    color: accent,
    fontSize: Math.round(10 * scale),
    fontWeight: boldLabels ? '700' as const : '500' as const,
    textTransform: 'uppercase' as const,
    letterSpacing: 0.5,
  }), [accent, scale, boldLabels]);

  const statValueStyle = useMemo(() => ({
    color: colors.text,
    fontSize: Math.round(17 * scale),
    fontWeight: '600' as const,
    marginTop: 2,
  }), [scale]);

  async function handleStart() {
    const granted = await requestLocationPermissions();
    if (!granted) { Alert.alert('Permission required', 'Location permission is required to record.'); return; }
    start();
    await startGpsRecording();
  }

  async function handlePause()  { await stopGpsRecording(); pause(); }
  async function handleResume() { resume(); await startGpsRecording(); }
  async function handleStop()   { await stopGpsRecording(); stop(); nav.navigate('PostRecording'); }

  const formatDuration = (secs: number) => {
    const h = Math.floor(secs / 3600).toString().padStart(2, '0');
    const m = Math.floor((secs % 3600) / 60).toString().padStart(2, '0');
    const s = (secs % 60).toString().padStart(2, '0');
    return `${h}:${m}:${s}`;
  };

  return (
    <View style={styles.container}>
      <View style={styles.statsGrid}>
        <StatBox label="Time"      value={formatDuration(stats.elapsedSeconds)} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Distance"  value={`${(stats.distanceMeters / 1000).toFixed(2)} km`} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Speed"     value={`${stats.currentSpeedKph.toFixed(1)} km/h`} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Avg Speed" value={`${stats.avgSpeedKph.toFixed(1)} km/h`} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Elevation" value={`+${stats.elevationGainMeters.toFixed(0)} m`} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="HR"        value={ble.hr      ? `${ble.hr} bpm`      : '—'} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Power"     value={ble.power   ? `${ble.power} W`     : '—'} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
        <StatBox label="Cadence"   value={ble.cadence ? `${ble.cadence} rpm` : '—'} labelStyle={statLabelStyle} valueStyle={statValueStyle} />
      </View>

      <View style={styles.mapArea}>
        <Map mapStyle={MAP_STYLE} style={StyleSheet.absoluteFill} logo={false} attribution={false}>
          <Camera
            trackUserLocation={status === 'recording' ? 'course' : undefined}
            initialViewState={{ zoom: 14 }}
          />
          <UserLocation />
          {trackPoints.length >= 2 && (
            <GeoJSONSource id="track" data={trackGeoJSON}>
              <Layer id="track-line" type="line" style={trackLineStyle} />
            </GeoJSONSource>
          )}
        </Map>
        <TouchableOpacity style={[styles.sensorBtn, { borderColor: colors.border }]} onPress={() => nav.navigate('SensorPairing')}>
          <Text style={[styles.sensorBtnText, { color: accent }]}>⚡ Sensors</Text>
        </TouchableOpacity>
      </View>

      <View style={styles.controls}>
        <TouchableOpacity
          style={[styles.awakeBtn, keepAwake && { borderColor: accent }]}
          onPress={() => setKeepAwake(!keepAwake)}
        >
          <Text style={styles.awakeBtnText}>{keepAwake ? '◑ Awake' : '◌ Sleep'}</Text>
        </TouchableOpacity>

        {status === 'idle' && (
          <TouchableOpacity style={[styles.btn, styles.btnStart]} onPress={handleStart}>
            <Text style={styles.btnText}>Start</Text>
          </TouchableOpacity>
        )}
        {status === 'recording' && (
          <>
            <TouchableOpacity style={[styles.btn, styles.btnPause]} onPress={handlePause}>
              <Text style={styles.btnText}>Pause</Text>
            </TouchableOpacity>
            <TouchableOpacity style={[styles.btn, styles.btnStop]} onPress={handleStop}>
              <Text style={styles.btnText}>Stop</Text>
            </TouchableOpacity>
          </>
        )}
        {status === 'paused' && (
          <>
            <TouchableOpacity style={[styles.btn, styles.btnStart]} onPress={handleResume}>
              <Text style={styles.btnText}>Resume</Text>
            </TouchableOpacity>
            <TouchableOpacity style={[styles.btn, styles.btnStop]} onPress={handleStop}>
              <Text style={styles.btnText}>Stop</Text>
            </TouchableOpacity>
          </>
        )}
      </View>
    </View>
  );
}

function StatBox({ label, value, labelStyle, valueStyle }: {
  label: string; value: string;
  labelStyle: object; valueStyle: object;
}) {
  return (
    <View style={styles.statBox}>
      <Text style={labelStyle}>{label}</Text>
      <Text style={valueStyle}>{value}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container:     { flex: 1, backgroundColor: colors.bg },
  statsGrid:     { flexDirection: 'row', flexWrap: 'wrap', padding: 8, borderBottomWidth: 1, borderBottomColor: colors.border },
  statBox:       { width: '25%', padding: 8, alignItems: 'center' },
  mapArea:       { flex: 1, overflow: 'hidden' },
  sensorBtn:     { position: 'absolute', top: 10, right: 10, backgroundColor: 'rgba(9,9,11,0.8)', borderRadius: 8, borderWidth: 1, paddingVertical: 6, paddingHorizontal: 12 },
  sensorBtnText: { fontSize: 13, fontWeight: '600' },
  controls:      { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 12, padding: 20, borderTopWidth: 1, borderTopColor: colors.border },
  awakeBtn:      { backgroundColor: colors.surface, borderRadius: 20, borderWidth: 1, borderColor: colors.border, paddingVertical: 8, paddingHorizontal: 14 },
  awakeBtnText:  { color: colors.textSub, fontSize: 13 },
  btn:           { paddingVertical: 15, paddingHorizontal: 30, borderRadius: 50 },
  btnStart:      { backgroundColor: colors.btnStart },
  btnPause:      { backgroundColor: colors.btnPause },
  btnStop:       { backgroundColor: colors.btnStop },
  btnText:       { color: '#fff', fontSize: 17, fontWeight: '700' },
});
