import React, { useState, useRef, useEffect } from 'react';
import { View, Text, StyleSheet, ScrollView, Alert, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import WebView from 'react-native-webview';
import { useRouter } from 'expo-router';
import { useAuth } from '@/context/AuthContext';
import { BoardingHouseAPI } from '@/services/api';
import { Input } from '@/components/ui/Input';
import { Button } from '@/components/ui/Button';
import { ScreenHeader } from '@/components/ui/ScreenHeader';
import { Card } from '@/components/ui/Card';
import { Colors, FontSize, Spacing, Radius } from '@/constants/theme';
import { Ionicons } from '@expo/vector-icons';
import * as Location from 'expo-location';

// Static HTML — never rebuilt. Pin is moved via injectJavaScript.
const PICKER_HTML = `<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
  <style>
    html,body,#map{margin:0;padding:0;height:100%;width:100%;}
    .gps-dot{width:16px;height:16px;border-radius:50%;background:#2ECC71;border:3px solid #fff;box-shadow:0 0 0 3px rgba(46,204,113,.3);}
  </style>
</head>
<body>
<div id="map"></div>
<script>
  var DEFAULT_LAT = 10.3157, DEFAULT_LNG = 123.8854;
  var map = L.map('map',{zoomControl:true}).setView([DEFAULT_LAT,DEFAULT_LNG],15);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{maxZoom:19}).addTo(map);

  // Draggable pin marker
  var pinIcon = L.divIcon({
    className:'',
    html:'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="0 0 32 40"><path d="M16 0C7.163 0 0 7.163 0 16c0 10 16 24 16 24s16-14 16-24C32 7.163 24.837 0 16 0z" fill="#1E3A5F"/><circle cx="16" cy="16" r="7" fill="#fff"/><path d="M16 10v6l4 2" stroke="#1E3A5F" stroke-width="2" fill="none" stroke-linecap="round"/></svg>',
    iconSize:[32,40],iconAnchor:[16,40]
  });
  var marker = L.marker([DEFAULT_LAT,DEFAULT_LNG],{icon:pinIcon,draggable:true}).addTo(map);

  // GPS user dot
  var gpsMarker = null;

  function reportPos(lat,lng){
    window.ReactNativeWebView.postMessage(JSON.stringify({type:'pin',lat:lat,lng:lng}));
  }
  function reportDrag(dragging){
    window.ReactNativeWebView.postMessage(JSON.stringify({type:'dragging',value:dragging}));
  }

  marker.on('dragstart',function(){ reportDrag(true); });
  marker.on('dragend',function(e){
    var p=e.target.getLatLng();
    reportDrag(false);
    reportPos(p.lat,p.lng);
  });
  map.on('click',function(e){
    marker.setLatLng(e.latlng);
    reportPos(e.latlng.lat,e.latlng.lng);
  });

  // Commands from RN
  function handleMsg(e){
    try{
      var m=JSON.parse(e.data);
      if(m.type==='movePinTo'){
        var ll=[m.lat,m.lng];
        marker.setLatLng(ll);
        map.setView(ll,16);
        reportPos(m.lat,m.lng);
      }
      if(m.type==='gpsLocation'){
        var ll=[m.lat,m.lng];
        if(!gpsMarker){
          var gpsIcon=L.divIcon({className:'',html:'<div class="gps-dot"></div>',iconSize:[16,16],iconAnchor:[8,8]});
          gpsMarker=L.marker(ll,{icon:gpsIcon,zIndexOffset:500}).addTo(map);
        } else {
          gpsMarker.setLatLng(ll);
        }
      }
    }catch(err){}
  }
  document.addEventListener('message',handleMsg);
  window.addEventListener('message',handleMsg);
  window.ReactNativeWebView.postMessage(JSON.stringify({type:'ready'}));
</script>
</body>
</html>`;

function injectToMap(ref: React.RefObject<InstanceType<typeof WebView> | null>, payload: object) {
  ref.current?.injectJavaScript(`
    (function(){
      var e=new MessageEvent('message',{data:${JSON.stringify(JSON.stringify(payload))}});
      window.dispatchEvent(e);document.dispatchEvent(e);
    })();true;
  `);
}

export default function AddPropertyScreen() {
  const { user } = useAuth();
  const router = useRouter();
  const webViewRef = useRef<InstanceType<typeof WebView>>(null);
  const mapReady = useRef(false);

  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  const [description, setDescription] = useState('');
  const [rentPrice, setRentPrice] = useState('');
  const [totalRooms, setTotalRooms] = useState('');
  const [availableRooms, setAvailableRooms] = useState('');
  const [electricityBilling, setElectricityBilling] = useState<'metered' | 'fixed'>('metered');
  const [electricityRate, setElectricityRate] = useState('');
  const [waterBilling, setWaterBilling] = useState<'metered' | 'fixed'>('metered');
  const [waterRate, setWaterRate] = useState('');
  const [lat, setLat] = useState(10.3157);
  const [lng, setLng] = useState(123.8854);
  const [showMap, setShowMap] = useState(false);
  const [loading, setLoading] = useState(false);
  const [locating, setLocating] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});

  async function locateMe() {
    setLocating(true);
    try {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') { Alert.alert('Permission denied', 'Location permission is required.'); return; }
      const pos = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High });
      const { latitude, longitude } = pos.coords;
      setLat(latitude);
      setLng(longitude);
      // Show GPS dot + move pin to current location
      injectToMap(webViewRef, { type: 'gpsLocation', lat: latitude, lng: longitude });
      injectToMap(webViewRef, { type: 'movePinTo', lat: latitude, lng: longitude });
      // Start watching so GPS dot stays live
      Location.watchPositionAsync(
        { accuracy: Location.Accuracy.Balanced, distanceInterval: 5, timeInterval: 3000 },
        (loc) => injectToMap(webViewRef, { type: 'gpsLocation', lat: loc.coords.latitude, lng: loc.coords.longitude })
      );
    } catch { Alert.alert('Error', 'Could not get location.'); }
    finally { setLocating(false); }
  }

  function validate() {
    const e: Record<string, string> = {};
    if (!name.trim()) e.name = 'Property name is required';
    if (!address.trim()) e.address = 'Address is required';
    if (!rentPrice || isNaN(Number(rentPrice))) e.rentPrice = 'Valid rent price required';
    if (!totalRooms || isNaN(Number(totalRooms))) e.totalRooms = 'Total rooms required';
    if (!availableRooms || isNaN(Number(availableRooms))) e.availableRooms = 'Available rooms required';
    setErrors(e);
    return Object.keys(e).length === 0;
  }

  async function handleSubmit() {
    if (!validate()) return;
    setLoading(true);
    try {
      await BoardingHouseAPI.create({
        landlord_id: user!.id,
        name: name.trim(),
        address: address.trim(),
        description: description.trim(),
        rent_price: parseFloat(rentPrice),
        total_rooms: parseInt(totalRooms),
        available_rooms: parseInt(availableRooms),
        electricity_billing: electricityBilling,
        electricity_rate: electricityBilling === 'fixed' ? parseFloat(electricityRate) : 0,
        water_billing: waterBilling,
        water_rate: waterBilling === 'fixed' ? parseFloat(waterRate) : 0,
        latitude: lat,
        longitude: lng,
      });
      Alert.alert('Success', 'Property added successfully!', [{ text: 'OK', onPress: () => router.back() }]);
    } catch (err: any) {
      Alert.alert('Error', err.message);
    } finally {
      setLoading(false);
    }
  }

  return (
    <SafeAreaView style={styles.safe} edges={['top']}>
      <ScreenHeader title="Add Property" showBack />
      <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled" scrollEnabled={!isDragging}>
        <Input label="Property Name" placeholder="e.g. Sunshine Boarding House" value={name} onChangeText={setName} leftIcon="home-outline" error={errors.name} />
        <Input label="Address" placeholder="Full address" value={address} onChangeText={setAddress} leftIcon="location-outline" error={errors.address} />
        <Input label="Description (optional)" placeholder="Describe your property..." value={description} onChangeText={setDescription} multiline style={{ height: 80 }} />

        <View style={styles.row}>
          <View style={styles.half}>
            <Input label="Rent Price (₱)" placeholder="3500" value={rentPrice} onChangeText={setRentPrice} keyboardType="numeric" leftIcon="cash-outline" error={errors.rentPrice} />
          </View>
          <View style={styles.half}>
            <Input label="Total Rooms" placeholder="10" value={totalRooms} onChangeText={setTotalRooms} keyboardType="numeric" error={errors.totalRooms} />
          </View>
        </View>

        <Input label="Available Rooms" placeholder="5" value={availableRooms} onChangeText={setAvailableRooms} keyboardType="numeric" error={errors.availableRooms} />

        {/* Electricity */}
        <Card style={styles.utilCard}>
          <Text style={styles.utilTitle}>Electricity Billing</Text>
          <View style={styles.billingRow}>
            {(['metered', 'fixed'] as const).map(b => (
              <TouchableOpacity key={b} onPress={() => setElectricityBilling(b)} style={[styles.billingBtn, electricityBilling === b && styles.billingBtnActive]}>
                <Text style={[styles.billingText, electricityBilling === b && styles.billingTextActive]}>{b.charAt(0).toUpperCase() + b.slice(1)}</Text>
              </TouchableOpacity>
            ))}
          </View>
          {electricityBilling === 'fixed' && (
            <Input label="Monthly Rate (₱)" placeholder="500" value={electricityRate} onChangeText={setElectricityRate} keyboardType="numeric" />
          )}
        </Card>

        {/* Water */}
        <Card style={styles.utilCard}>
          <Text style={styles.utilTitle}>Water Billing</Text>
          <View style={styles.billingRow}>
            {(['metered', 'fixed'] as const).map(b => (
              <TouchableOpacity key={b} onPress={() => setWaterBilling(b)} style={[styles.billingBtn, waterBilling === b && styles.billingBtnActive]}>
                <Text style={[styles.billingText, waterBilling === b && styles.billingTextActive]}>{b.charAt(0).toUpperCase() + b.slice(1)}</Text>
              </TouchableOpacity>
            ))}
          </View>
          {waterBilling === 'fixed' && (
            <Input label="Monthly Rate (₱)" placeholder="200" value={waterRate} onChangeText={setWaterRate} keyboardType="numeric" />
          )}
        </Card>

        {/* Map Picker */}
        <Card style={styles.mapCard}>
          <View style={styles.mapHeader}>
            <Text style={styles.utilTitle}>Pin Location</Text>
            <View style={styles.mapActions}>
              <TouchableOpacity onPress={locateMe} style={styles.locateBtn} disabled={locating}>
                <Ionicons name="locate" size={16} color={locating ? Colors.textLight : Colors.primary} />
                <Text style={[styles.mapToggle, locating && { color: Colors.textLight }]}>
                  {locating ? 'Locating...' : 'Use GPS'}
                </Text>
              </TouchableOpacity>
              <TouchableOpacity onPress={() => setShowMap(!showMap)}>
                <Text style={styles.mapToggle}>{showMap ? 'Hide Map' : 'Open Map'}</Text>
              </TouchableOpacity>
            </View>
          </View>
          <Text style={styles.coordText}>📍 {lat.toFixed(6)}, {lng.toFixed(6)}</Text>
          {showMap && (
            <View style={styles.mapWrapper}>
              <WebView
                ref={webViewRef}
                source={{ html: PICKER_HTML }}
                style={styles.map}
                onMessage={e => {
                  try {
                    const msg = JSON.parse(e.nativeEvent.data);
                    if (msg.type === 'ready') { mapReady.current = true; }
                    if (msg.type === 'dragging') { setIsDragging(msg.value); }
                    if (msg.type === 'pin') { setLat(msg.lat); setLng(msg.lng); }
                  } catch (_) {}
                }}
                javaScriptEnabled
                domStorageEnabled
                originWhitelist={['*']}
              />
              <View style={styles.mapHint}>
                <Ionicons name="information-circle-outline" size={13} color={Colors.textSecondary} />
                <Text style={styles.mapHintText}>Tap map or drag pin to set location</Text>
              </View>
            </View>
          )}
        </Card>

        <Button title="Add Property" onPress={handleSubmit} loading={loading} style={styles.submitBtn} />
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safe: { flex: 1, backgroundColor: Colors.background },
  content: { padding: Spacing.md, paddingBottom: Spacing.xl },
  row: { flexDirection: 'row', gap: Spacing.sm },
  half: { flex: 1 },
  utilCard: { marginBottom: Spacing.md, gap: Spacing.sm },
  utilTitle: { fontSize: FontSize.md, fontWeight: '700', color: Colors.text },
  billingRow: { flexDirection: 'row', gap: Spacing.sm },
  billingBtn: { flex: 1, paddingVertical: Spacing.sm, borderRadius: Radius.md, borderWidth: 1.5, borderColor: Colors.border, alignItems: 'center' },
  billingBtnActive: { backgroundColor: Colors.primary, borderColor: Colors.primary },
  billingText: { fontSize: FontSize.sm, fontWeight: '600', color: Colors.textSecondary },
  billingTextActive: { color: Colors.textInverse },
  mapCard: { marginBottom: Spacing.md, gap: Spacing.sm },
  mapHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  mapActions: { flexDirection: 'row', alignItems: 'center', gap: Spacing.md },
  locateBtn: { flexDirection: 'row', alignItems: 'center', gap: 4 },
  mapToggle: { fontSize: FontSize.sm, color: Colors.primary, fontWeight: '600' },
  coordText: { fontSize: FontSize.sm, color: Colors.textSecondary },
  mapWrapper: { gap: Spacing.xs },
  map: { height: 280, borderRadius: Radius.md, overflow: 'hidden' },
  mapHint: { flexDirection: 'row', alignItems: 'center', gap: 4 },
  mapHintText: { fontSize: FontSize.xs, color: Colors.textSecondary },
  submitBtn: { marginTop: Spacing.sm },
});
