/**
 * MissionDetailScreen — uppdragsinfo, karta, acceptera-knapp, kamera-upload vid leverans
 * Live markör, distance overlay, heading indicator
 */
import { useEffect, useState, useRef, useCallback } from 'react'
import {
  View, Text, ScrollView, TouchableOpacity,
  StyleSheet, ActivityIndicator, Alert,
  Image, Platform,
} from 'react-native'
import MapView, { Marker, Region, PROVIDER_DEFAULT } from 'react-native-maps'
import * as ImagePicker from 'expo-image-picker'
import { useNavigation, useRoute, type RouteProp } from '@react-navigation/native'
import { missions, type MissionDetail } from '../lib/api'
import { useLocationStore } from '../src/stores/locationStore'
import { UserLocationMarker } from '../src/components/gps/UserLocationMarker'
import { FollowUserButton } from '../src/components/gps/FollowUserButton'

type RouteParams = { MissionDetail: { missionId: string } }

const CATEGORY_EMOJI: Record<string, string> = {
  infrastruktur: '🏗️',
  vägar: '🛤️',
  hamnar: '⚓',
  bryggor: '🚢',
  fritidshus: '🏠',
  miljö: '🌿',
  övrigt: '📍',
}

/** Calculate distance between two coordinates in meters */
function haversineDistance(lat1: number, lng1: number, lat2: number, lng2: number): number {
  const R = 6371e3 // Earth radius in meters
  const φ1 = (lat1 * Math.PI) / 180
  const φ2 = (lat2 * Math.PI) / 180
  const Δφ = ((lat2 - lat1) * Math.PI) / 180
  const Δλ = ((lng2 - lng1) * Math.PI) / 180

  const a =
    Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
    Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2)
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))

  return R * c
}

function formatDistance(meters: number): string {
  if (meters < 1000) {
    return `${Math.round(meters)} m`
  }
  return `${(meters / 1000).toFixed(1)} km`
}

/** Calculate bearing from point 1 to point 2 in degrees */
function calculateBearing(lat1: number, lng1: number, lat2: number, lng2: number): number {
  const φ1 = (lat1 * Math.PI) / 180
  const φ2 = (lat2 * Math.PI) / 180
  const Δλ = ((lng2 - lng1) * Math.PI) / 180

  const y = Math.sin(Δλ) * Math.cos(φ2)
  const x =
    Math.cos(φ1) * Math.sin(φ2) -
    Math.sin(φ1) * Math.cos(φ2) * Math.cos(Δλ)

  const θ = Math.atan2(y, x)
  return ((θ * 180) / Math.PI + 360) % 360
}

function getDirectionArrow(degrees: number): string {
  if (degrees >= 337.5 || degrees < 22.5) return '↑'
  if (degrees >= 22.5 && degrees < 67.5) return '↗'
  if (degrees >= 67.5 && degrees < 112.5) return '→'
  if (degrees >= 112.5 && degrees < 157.5) return '↘'
  if (degrees >= 157.5 && degrees < 202.5) return '↓'
  if (degrees >= 202.5 && degrees < 247.5) return '↙'
  if (degrees >= 247.5 && degrees < 292.5) return '←'
  return '↖'
}

export function MissionDetailScreen() {
  const navigation = useNavigation<any>()
  const route = useRoute<RouteProp<RouteParams, 'MissionDetail'>>()
  const { missionId } = route.params
  const mapRef = useRef<MapView>(null)

  // Live location from store
  const {
    currentPosition,
    heading,
    followUser,
    setUserPannedMap,
  } = useLocationStore()

  const [mission, setMission] = useState<MissionDetail | null>(null)
  const [loading, setLoading] = useState(true)
  const [accepting, setAccepting] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [accepted, setAccepted] = useState(false)
  const [mediaUris, setMediaUris] = useState<string[]>([])
  const [distance, setDistance] = useState<number | null>(null)
  const [bearing, setBearing] = useState<number | null>(null)

  useEffect(() => {
    missions.get(missionId)
      .then(m => { setMission(m); setLoading(false) })
      .catch(() => { Alert.alert('Fel', 'Kunde inte hämta uppdraget.'); navigation.goBack() })
  }, [missionId])

  // Update distance and bearing when position or mission changes
  useEffect(() => {
    if (currentPosition && mission) {
      const dist = haversineDistance(
        currentPosition.coords.latitude,
        currentPosition.coords.longitude,
        mission.latitude,
        mission.longitude
      )
      setDistance(dist)

      const bear = calculateBearing(
        currentPosition.coords.latitude,
        currentPosition.coords.longitude,
        mission.latitude,
        mission.longitude
      )
      setBearing(bear)
    }
  }, [currentPosition, mission])

  // Auto-follow user when followUser is true
  useEffect(() => {
    if (followUser && currentPosition && mapRef.current) {
      const region: Region = {
        latitude: currentPosition.coords.latitude,
        longitude: currentPosition.coords.longitude,
        latitudeDelta: 0.05,
        longitudeDelta: 0.05,
      }
      mapRef.current.animateToRegion(region, 300)
    }
  }, [currentPosition, followUser])

  const onPanDrag = useCallback(() => {
    setUserPannedMap(true)
  }, [setUserPannedMap])

  const handleAccept = async () => {
    if (!mission) return
    setAccepting(true)
    try {
      await missions.accept(mission.id)
      setAccepted(true)
      Alert.alert('✅ Uppdraget accepterat!', 'Ta dig till platsen och leverera när du är framme.')
    } catch (e: any) {
      Alert.alert('Fel', e?.message ?? 'Kunde inte acceptera uppdraget.')
    } finally {
      setAccepting(false)
    }
  }

  const handlePickMedia = async () => {
    const { status } = await ImagePicker.requestCameraPermissionsAsync()
    if (status !== 'granted') {
      Alert.alert('Kamera-åtkomst krävs', 'Tillåt kameraåtkomst i telefonens inställningar.')
      return
    }

    Alert.alert('Välj källa', '', [
      {
        text: 'Ta foto',
        onPress: async () => {
          const result = await ImagePicker.launchCameraAsync({
            mediaTypes: ImagePicker.MediaTypeOptions.Images,
            quality: 0.85,
            allowsEditing: false,
          })
          if (!result.canceled && result.assets[0]) {
            setMediaUris(prev => [...prev, result.assets[0].uri])
          }
        },
      },
      {
        text: 'Välj från bibliotek',
        onPress: async () => {
          const result = await ImagePicker.launchImageLibraryAsync({
            mediaTypes: ImagePicker.MediaTypeOptions.Images,
            quality: 0.85,
            allowsMultipleSelection: true,
            selectionLimit: 10,
          })
          if (!result.canceled) {
            setMediaUris(prev => [...prev, ...result.assets.map(a => a.uri)])
          }
        },
      },
      { text: 'Avbryt', style: 'cancel' },
    ])
  }

  const handleSubmit = async () => {
    if (!mission) return
    if (mediaUris.length === 0) {
      Alert.alert('Inga bilder', 'Lägg till minst en bild innan du skickar in.')
      return
    }

    Alert.alert(
      'Skicka in uppdraget?',
      `${mediaUris.length} bild${mediaUris.length > 1 ? 'er' : ''} kommer att skickas.`,
      [
        { text: 'Avbryt', style: 'cancel' },
        {
          text: 'Skicka in',
          onPress: async () => {
            setSubmitting(true)
            try {
              await missions.submit(mission.id, mediaUris)
              Alert.alert(
                '🎉 Inlämnat!',
                `Dina bilder granskas. Om allt godkänns får du ${(mission.reward_amount / 100).toFixed(0)} kr.`,
                [{ text: 'Tillbaka', onPress: () => navigation.goBack() }],
              )
            } catch (e: any) {
              Alert.alert('Fel', e?.message ?? 'Kunde inte skicka in uppdraget.')
            } finally {
              setSubmitting(false)
            }
          },
        },
      ],
    )
  }

  if (loading) {
    return (
      <View style={styles.center}>
        <ActivityIndicator color="#6366f1" size="large" />
      </View>
    )
  }

  if (!mission) return null

  const isExpired = mission.deadline_at ? new Date(mission.deadline_at) < new Date() : false
  const spotsLeft = mission.max_submissions - mission.submission_count

  // Calculate relative bearing for navigation arrow
  const relativeBearing = bearing != null && heading != null
    ? ((bearing - heading + 360) % 360)
    : null

  return (
    <View style={styles.container}>
      <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{ paddingBottom: 120 }}>

        {/* Header */}
        <View style={styles.header}>
          <TouchableOpacity style={styles.backBtn} onPress={() => navigation.goBack()}>
            <Text style={styles.backBtnText}>← Tillbaka</Text>
          </TouchableOpacity>
        </View>

        {/* Map with live tracking */}
        <View style={styles.mapContainer}>
          <MapView
            ref={mapRef}
            style={styles.map}
            provider={PROVIDER_DEFAULT}
            region={{
              latitude: mission.latitude,
              longitude: mission.longitude,
              latitudeDelta: 0.05,
              longitudeDelta: 0.05,
            }}
            onPanDrag={onPanDrag}
            showsUserLocation={false} // Custom marker
            rotateEnabled={false}
          >
            {/* Mission marker */}
            <Marker
              coordinate={{ latitude: mission.latitude, longitude: mission.longitude }}
              pinColor="#10b981"
              title={mission.title}
            />

            {/* Live user location marker */}
            {currentPosition && (
              <Marker
                coordinate={{
                  latitude: currentPosition.coords.latitude,
                  longitude: currentPosition.coords.longitude,
                }}
                anchor={{ x: 0.5, y: 0.5 }}
                flat={true}
              >
                <UserLocationMarker />
              </Marker>
            )}
          </MapView>

          {/* Follow user button */}
          <View style={styles.followBtnContainer}>
            <FollowUserButton />
          </View>

          {/* Distance overlay */}
          {distance != null && (
            <View style={styles.distanceOverlay}>
              <View style={styles.distanceRow}>
                <Text style={styles.distanceLabel}>Avstånd till uppdrag</Text>
                <Text style={styles.distanceValue}>{formatDistance(distance)}</Text>
              </View>
              {relativeBearing != null && (
                <View style={styles.distanceRow}>
                  <Text style={styles.distanceLabel}>Riktning</Text>
                  <Text style={styles.distanceValue}>
                    {getDirectionArrow(relativeBearing)} {relativeBearing.toFixed(0)}°
                  </Text>
                </View>
              )}
              {heading != null && (
                <View style={styles.distanceRow}>
                  <Text style={styles.distanceLabel}>Din kurs</Text>
                  <Text style={styles.distanceValue}>{heading.toFixed(0)}°</Text>
                </View>
              )}
              {currentPosition?.coords.speed != null && (
                <View style={styles.distanceRow}>
                  <Text style={styles.distanceLabel}>Hastighet</Text>
                  <Text style={styles.distanceValue}>
                    {(currentPosition.coords.speed * 3.6).toFixed(1)} km/h
                  </Text>
                </View>
              )}
            </View>
          )}
        </View>

        {/* Content */}
        <View style={styles.content}>
          {/* Category + status row */}
          <View style={styles.metaRow}>
            <View style={styles.categoryBadge}>
              <Text style={styles.categoryEmoji}>{CATEGORY_EMOJI[mission.category] ?? '📍'}</Text>
              <Text style={styles.categoryText}>{mission.category}</Text>
            </View>
            {isExpired && <View style={styles.expiredBadge}><Text style={styles.expiredText}>Utgången</Text></View>}
            {spotsLeft <= 3 && !isExpired && (
              <View style={styles.urgentBadge}>
                <Text style={styles.urgentText}>Bara {spotsLeft} platser kvar</Text>
              </View>
            )}
          </View>

          {/* Title */}
          <Text style={styles.title}>{mission.title}</Text>

          {/* Reward + deadline */}
          <View style={styles.rewardRow}>
            <View style={styles.rewardBox}>
              <Text style={styles.rewardLabel}>Ersättning</Text>
              <Text style={styles.rewardValue}>{(mission.reward_amount / 100).toFixed(0)} SEK</Text>
            </View>
            {mission.deadline_at && (
              <View style={styles.rewardBox}>
                <Text style={styles.rewardLabel}>Deadline</Text>
                <Text style={styles.rewardValue}>
                  {new Date(mission.deadline_at).toLocaleDateString('sv-SE', {
                    month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',
                  })}
                </Text>
              </View>
            )}
            <View style={styles.rewardBox}>
              <Text style={styles.rewardLabel}>Plats</Text>
              <Text style={styles.rewardValue}>{mission.city || 'Skärgården'}</Text>
            </View>
          </View>

          {/* Description */}
          <Text style={styles.sectionTitle}>Beskrivning</Text>
          <Text style={styles.desc}>{mission.description}</Text>

          {/* Instructions */}
          {mission.instructions && (
            <>
              <Text style={styles.sectionTitle}>Instruktioner</Text>
              <Text style={styles.desc}>{mission.instructions}</Text>
            </>
          )}

          {/* Requirements */}
          {mission.requirements?.length > 0 && (
            <>
              <Text style={styles.sectionTitle}>Krav</Text>
              {mission.requirements.map((r, i) => (
                <View key={i} style={styles.reqRow}>
                  <Text style={styles.reqBullet}>✓</Text>
                  <Text style={styles.reqText}>{r}</Text>
                </View>
              ))}
            </>
          )}

          {/* Media picker (only when accepted) */}
          {accepted && (
            <>
              <Text style={styles.sectionTitle}>Dina bilder</Text>
              <View style={styles.mediaGrid}>
                {mediaUris.map((uri, i) => (
                  <View key={i} style={styles.mediaThumbWrap}>
                    <Image source={{ uri }} style={styles.mediaThumb} />
                    <TouchableOpacity
                      style={styles.removeBtn}
                      onPress={() => setMediaUris(prev => prev.filter((_, j) => j !== i))}
                    >
                      <Text style={styles.removeBtnText}>✕</Text>
                    </TouchableOpacity>
                  </View>
                ))}
                <TouchableOpacity style={styles.addMediaBtn} onPress={handlePickMedia}>
                  <Text style={styles.addMediaIcon}>📸</Text>
                  <Text style={styles.addMediaText}>Lägg till bild</Text>
                </TouchableOpacity>
              </View>
            </>
          )}
        </View>
      </ScrollView>

      {/* Bottom action bar */}
      {!isExpired && (
        <View style={styles.bottomBar}>
          {!accepted ? (
            <TouchableOpacity
              style={[styles.actionBtn, accepting && styles.actionBtnDisabled]}
              onPress={handleAccept}
              disabled={accepting}
            >
              {accepting
                ? <ActivityIndicator color="#fff" />
                : <Text style={styles.actionBtnText}>🎯 Acceptera uppdraget</Text>
              }
            </TouchableOpacity>
          ) : (
            <TouchableOpacity
              style={[styles.actionBtn, styles.submitBtn, (submitting || mediaUris.length === 0) && styles.actionBtnDisabled]}
              onPress={handleSubmit}
              disabled={submitting || mediaUris.length === 0}
            >
              {submitting
                ? <ActivityIndicator color="#fff" />
                : <Text style={styles.actionBtnText}>
                    📤 Skicka in ({mediaUris.length} bild{mediaUris.length !== 1 ? 'er' : ''})
                  </Text>
              }
            </TouchableOpacity>
          )}
        </View>
      )}
    </View>
  )
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#0A0A1B' },
  center: { flex: 1, backgroundColor: '#0A0A1B', alignItems: 'center', justifyContent: 'center' },

  header: {
    paddingTop: Platform.OS === 'ios' ? 56 : 16,
    paddingHorizontal: 16,
    paddingBottom: 8,
  },
  backBtn: { paddingVertical: 4 },
  backBtnText: { color: '#6366f1', fontSize: 15, fontWeight: '600' },

  mapContainer: {
    height: 280,
    position: 'relative',
  },
  map: {
    flex: 1,
  },

  followBtnContainer: {
    position: 'absolute',
    bottom: 16,
    right: 16,
  },

  distanceOverlay: {
    position: 'absolute',
    top: 16,
    left: 16,
    backgroundColor: 'rgba(10,10,27,0.85)',
    borderRadius: 12,
    padding: 12,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.1)',
    minWidth: 160,
  },
  distanceRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 4,
  },
  distanceLabel: {
    color: 'rgba(255,255,255,0.45)',
    fontSize: 11,
    marginRight: 12,
  },
  distanceValue: {
    color: '#fff',
    fontSize: 13,
    fontWeight: '700',
  },

  content: { padding: 20 },

  metaRow: { flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 12 },
  categoryBadge: {
    flexDirection: 'row', alignItems: 'center', gap: 6,
    backgroundColor: 'rgba(99,102,241,0.15)',
    borderRadius: 20, paddingHorizontal: 12, paddingVertical: 6,
  },
  categoryEmoji: { fontSize: 14 },
  categoryText: { color: '#a5b4fc', fontSize: 12, fontWeight: '600', textTransform: 'capitalize' },
  expiredBadge: {
    backgroundColor: 'rgba(239,68,68,0.15)',
    borderRadius: 20, paddingHorizontal: 12, paddingVertical: 6,
  },
  expiredText: { color: '#ef4444', fontSize: 12, fontWeight: '600' },
  urgentBadge: {
    backgroundColor: 'rgba(245,158,11,0.15)',
    borderRadius: 20, paddingHorizontal: 12, paddingVertical: 6,
  },
  urgentText: { color: '#f59e0b', fontSize: 12, fontWeight: '600' },

  title: { color: '#fff', fontSize: 24, fontWeight: '800', lineHeight: 30, marginBottom: 20, letterSpacing: -0.5 },

  rewardRow: { flexDirection: 'row', gap: 12, marginBottom: 24 },
  rewardBox: {
    flex: 1,
    backgroundColor: 'rgba(255,255,255,0.04)',
    borderRadius: 14, padding: 14,
    borderWidth: 1, borderColor: 'rgba(255,255,255,0.07)',
  },
  rewardLabel: { color: 'rgba(255,255,255,0.4)', fontSize: 11, marginBottom: 4 },
  rewardValue: { color: '#fff', fontSize: 15, fontWeight: '700' },

  sectionTitle: { color: 'rgba(255,255,255,0.5)', fontSize: 12, fontWeight: '700', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 8, marginTop: 4 },
  desc: { color: 'rgba(255,255,255,0.7)', fontSize: 15, lineHeight: 24, marginBottom: 20 },

  reqRow: { flexDirection: 'row', gap: 10, marginBottom: 8 },
  reqBullet: { color: '#10b981', fontWeight: '700', fontSize: 14 },
  reqText: { color: 'rgba(255,255,255,0.65)', fontSize: 14, lineHeight: 20, flex: 1 },

  mediaGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 10, marginBottom: 8 },
  mediaThumbWrap: { position: 'relative' },
  mediaThumb: { width: 90, height: 90, borderRadius: 12 },
  removeBtn: {
    position: 'absolute', top: -6, right: -6,
    width: 22, height: 22, borderRadius: 11,
    backgroundColor: '#ef4444', alignItems: 'center', justifyContent: 'center',
  },
  removeBtnText: { color: '#fff', fontSize: 10, fontWeight: '800' },
  addMediaBtn: {
    width: 90, height: 90, borderRadius: 12,
    backgroundColor: 'rgba(255,255,255,0.04)',
    borderWidth: 2, borderColor: 'rgba(255,255,255,0.12)',
    borderStyle: 'dashed',
    alignItems: 'center', justifyContent: 'center', gap: 4,
  },
  addMediaIcon: { fontSize: 24 },
  addMediaText: { color: 'rgba(255,255,255,0.4)', fontSize: 11 },

  bottomBar: {
    position: 'absolute', bottom: 0, left: 0, right: 0,
    padding: 16,
    paddingBottom: Platform.OS === 'ios' ? 32 : 16,
    backgroundColor: 'rgba(10,10,27,0.95)',
    borderTopWidth: 1, borderTopColor: 'rgba(255,255,255,0.08)',
  },
  actionBtn: {
    backgroundColor: '#6366f1',
    borderRadius: 16, paddingVertical: 16,
    alignItems: 'center', justifyContent: 'center',
  },
  submitBtn: { backgroundColor: '#10b981' },
  actionBtnDisabled: { opacity: 0.5 },
  actionBtnText: { color: '#fff', fontWeight: '700', fontSize: 16 },
})
