import React, { useState, useRef } from 'react';

// Pure JavaScript GPS EXIF metadata reader
function getEXIFGPS(arrayBuffer) {
  const dataView = new DataView(arrayBuffer);
  if (dataView.getUint16(0, false) !== 0xFFD8) {
    return null; // Not a JPEG
  }
  let offset = 2;
  const length = dataView.byteLength;
  let exifOffset = null;
  
  while (offset < length) {
    const marker = dataView.getUint16(offset, false);
    offset += 2;
    if (marker === 0xFFE1) { // APP1 segment containing EXIF
      const segmentLength = dataView.getUint16(offset, false);
      if (dataView.getUint32(offset + 2, false) === 0x45786966) { // "Exif"
        exifOffset = offset + 8;
        break;
      }
      offset += segmentLength;
    } else if ((marker & 0xFF00) === 0xFF00) {
      const segmentLength = dataView.getUint16(offset, false);
      offset += segmentLength;
    } else {
      break;
    }
  }
  
  if (!exifOffset) return null;
  
  const littleEndian = dataView.getUint16(exifOffset, false) === 0x4949;
  const ifd0Offset = dataView.getUint32(exifOffset + 4, littleEndian);
  
  function parseIFD(offset, tiffOffset) {
    try {
      const entriesCount = dataView.getUint16(tiffOffset + offset, littleEndian);
      const tags = {};
      
      for (let i = 0; i < entriesCount; i++) {
        const entryOffset = tiffOffset + offset + 2 + i * 12;
        if (entryOffset + 12 > dataView.byteLength) break;
        const tag = dataView.getUint16(entryOffset, littleEndian);
        const type = dataView.getUint16(entryOffset + 2, littleEndian);
        const count = dataView.getUint32(entryOffset + 4, littleEndian);
        const valueOffset = dataView.getUint32(entryOffset + 8, littleEndian);
        
        tags[tag] = { type, count, offset: valueOffset, rawOffset: entryOffset + 8 };
      }
      return tags;
    } catch (e) {
      return {};
    }
  }
  
  try {
    const ifd0 = parseIFD(ifd0Offset, exifOffset);
    if (ifd0[0x8825]) { // GPS IFD Pointer
      const gpsOffset = ifd0[0x8825].offset;
      const gpsIFD = parseIFD(gpsOffset, exifOffset);
      
      const readRational = (valueOffset) => {
        const targetOffset = exifOffset + valueOffset;
        if (targetOffset + 8 > dataView.byteLength) return 0;
        const num = dataView.getUint32(targetOffset, littleEndian);
        const den = dataView.getUint32(targetOffset + 4, littleEndian);
        return den === 0 ? 0 : num / den;
      };
      
      const readCoordinate = (tag) => {
        if (!gpsIFD[tag]) return null;
        const offset = gpsIFD[tag].offset;
        const deg = readRational(offset);
        const min = readRational(offset + 8);
        const sec = readRational(offset + 16);
        return deg + min / 60 + sec / 3600;
      };
      
      let lat = readCoordinate(2); // GPSLatitude
      let lng = readCoordinate(4); // GPSLongitude
      
      if (lat !== null && lng !== null) {
        if (gpsIFD[1]) { // GPSLatitudeRef
          const refOffset = gpsIFD[1].rawOffset;
          const refChar = String.fromCharCode(dataView.getUint8(refOffset));
          if (refChar === 'S') lat = -lat;
        }
        if (gpsIFD[3]) { // GPSLongitudeRef
          const refOffset = gpsIFD[3].rawOffset;
          const refChar = String.fromCharCode(dataView.getUint8(refOffset));
          if (refChar === 'W') lng = -lng;
        }
        return { lat, lng };
      }
    }
  } catch (err) {
    console.error('GPS parsing error:', err);
  }
  return null;
}

export default function SurveyMethodModal({
  showSurveyModal,
  setShowSurveyModal,
  setPlacementMode,
  setShowToast,
  hubs,
  mapInstance,
  setHhFormData,
  setImageFile,
  setShowHhModal,
  showToastNotification,
  profile
}) {
  const [optionMode, setOptionMode] = useState(null); // 'upload' or null
  const [gpsData, setGpsData] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);
  const [tempFile, setTempFile] = useState(null);
  const fileInputRef = useRef(null);

  if (!showSurveyModal) return null;

  const resetSurveyModal = () => {
    setOptionMode(null);
    setGpsData(null);
    setErrorMsg(null);
    setTempFile(null);
  };

  const handleSelectMapOption = () => {
    setPlacementMode('household');
    setShowToast(true);
    setShowSurveyModal(false);
    resetSurveyModal();
  };

  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    setErrorMsg(null);
    setGpsData(null);
    setTempFile(null);

    const reader = new FileReader();
    reader.onload = (event) => {
      const buffer = event.target.result;
      const coords = getEXIFGPS(buffer);
      
      if (coords) {
        setGpsData(coords);
        setTempFile(file);
        showToastNotification('Metadata lokasi GPS berhasil ditarik!');
      } else {
        setErrorMsg('Foto ini tidak memiliki metadata lokasi GPS (geotag). Silakan ambil foto baru menggunakan kamera ponsel dengan mengaktifkan GPS / Lokasi, atau gunakan opsi "Tentukan Posisi Melalui Peta".');
      }
    };
    reader.onerror = () => {
      setErrorMsg('Gagal membaca berkas gambar.');
    };
    reader.readAsArrayBuffer(file);
  };

  const handleContinueSurvey = () => {
    if (!gpsData || !tempFile) return;

    // Spatially calculate closest hub using Haversine / Leaflet map distance
    let closestHub = null;
    let minDistance = Infinity;
    
    hubs.forEach(hub => {
      if (mapInstance && mapInstance.current) {
        const dist = mapInstance.current.distance([gpsData.lat, gpsData.lng], [hub.lat, hub.lng]);
        const hubRadius = parseInt(hub.radius) || 500;
        if (dist <= hubRadius && dist < minDistance) {
          minDistance = dist;
          closestHub = hub;
        }
      }
    });

    // For non-admin, if they use photo geotag, they can add anywhere.
    // If it's outside their own hub's radius, we assign it to their hub anyway but flag it with manual override.
    let finalAssignedHubId = closestHub ? closestHub.id : null;
    let forceManualOverride = false;

    if (profile?.role !== 'super_admin') {
      const myHub = hubs.find(h => h.pic_id === profile?.id || h.head_id === profile?.id);
      if (myHub) {
        const isInsideRadius = closestHub && closestHub.id === myHub.id;
        if (!isInsideRadius) {
          // Outside their hub's radius! Force assignment to myHub and flag with manual override
          finalAssignedHubId = myHub.id;
          forceManualOverride = true;
        }
      }
    }

    setHhFormData({
      id: '',
      head_name: '',
      nik: '',
      no_kk: '',
      family_size: 1,
      status: 'Pending',
      photo_url: '',
      lat: gpsData.lat,
      lng: gpsData.lng,
      assigned_hub_id: finalAssignedHubId,
      manual_override_assigned_hub: forceManualOverride
    });

    setImageFile(tempFile);
    setShowSurveyModal(false);
    setShowHhModal(true);
    resetSurveyModal();
  };

  return (
    <div className="modal-overlay active" onClick={() => { setShowSurveyModal(false); resetSurveyModal(); }}>
      <div 
        className="modal-content" 
        style={{ maxWidth: '500px', width: '90%', padding: '24px' }}
        onClick={(e) => e.stopPropagation()}
      >
        <div className="modal-header">
          <h2><i className="fas fa-house-medical text-primary"></i> Pendataan KK Baru</h2>
          <button className="close-btn" onClick={() => { setShowSurveyModal(false); resetSurveyModal(); }}>&times;</button>
        </div>

        <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
          
          {optionMode === null ? (
            <>
              <p style={{ margin: '0 0 10px 0', color: '#64748b', fontSize: '0.95rem', lineHeight: '1.5' }}>
                Silakan pilih salah satu opsi di bawah untuk menentukan lokasi koordinat rumah warga yang didata:
              </p>
              
              <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
                {/* Option 1: Map click */}
                <button
                  type="button"
                  onClick={handleSelectMapOption}
                  style={{
                    background: 'rgba(59, 130, 246, 0.08)',
                    border: '1px solid rgba(59, 130, 246, 0.25)',
                    borderRadius: '12px',
                    padding: '16px',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '16px',
                    cursor: 'pointer',
                    textAlign: 'left',
                    transition: 'all 0.2s',
                    width: '100%',
                    color: '#1e293b'
                  }}
                  onMouseOver={(e) => {
                    e.currentTarget.style.background = 'rgba(59, 130, 246, 0.15)';
                    e.currentTarget.style.transform = 'translateY(-2px)';
                  }}
                  onMouseOut={(e) => {
                    e.currentTarget.style.background = 'rgba(59, 130, 246, 0.08)';
                    e.currentTarget.style.transform = 'translateY(0)';
                  }}
                >
                  <div style={{
                    background: 'var(--primary, #3b82f6)',
                    color: 'white',
                    width: '40px', height: '40px', borderRadius: '50%',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: '1.25rem', flexShrink: 0
                  }}>
                    <i className="fas fa-map-location-dot"></i>
                  </div>
                  <div>
                    <h4 style={{ margin: '0 0 4px 0', fontSize: '0.95rem', fontWeight: '700' }}>Tentukan Posisi Melalui Peta</h4>
                    <p style={{ margin: 0, fontSize: '0.8rem', color: '#64748b' }}>Pilih lokasi rumah warga secara manual dengan menunjuknya langsung di peta interaktif.</p>
                  </div>
                </button>

                {/* Option 2: Geotagging upload */}
                <button
                  type="button"
                  onClick={() => setOptionMode('upload')}
                  style={{
                    background: 'rgba(16, 185, 129, 0.08)',
                    border: '1px solid rgba(16, 185, 129, 0.25)',
                    borderRadius: '12px',
                    padding: '16px',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '16px',
                    cursor: 'pointer',
                    textAlign: 'left',
                    transition: 'all 0.2s',
                    width: '100%',
                    color: '#1e293b'
                  }}
                  onMouseOver={(e) => {
                    e.currentTarget.style.background = 'rgba(16, 185, 129, 0.15)';
                    e.currentTarget.style.transform = 'translateY(-2px)';
                  }}
                  onMouseOut={(e) => {
                    e.currentTarget.style.background = 'rgba(16, 185, 129, 0.08)';
                    e.currentTarget.style.transform = 'translateY(0)';
                  }}
                >
                  <div style={{
                    background: 'var(--success, #10b981)',
                    color: 'white',
                    width: '40px', height: '40px', borderRadius: '50%',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: '1.25rem', flexShrink: 0
                  }}>
                    <i className="fas fa-camera-retro"></i>
                  </div>
                  <div>
                    <h4 style={{ margin: '0 0 4px 0', fontSize: '0.95rem', fontWeight: '700' }}>Unggah Foto dengan Geotag</h4>
                    <p style={{ margin: 0, fontSize: '0.8rem', color: '#64748b' }}>Ekstraksi koordinat otomatis dari metadata GPS foto rumah warga yang diambil langsung di lapangan.</p>
                  </div>
                </button>
              </div>
            </>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                <button 
                  type="button" 
                  onClick={() => setOptionMode(null)} 
                  style={{ background: 'none', border: 'none', color: '#64748b', cursor: 'pointer', fontSize: '0.9rem' }}
                >
                  <i className="fas fa-arrow-left"></i> Kembali
                </button>
              </div>

              <h4 style={{ fontSize: '0.95rem', fontWeight: '600', margin: 0 }}>Metode Unggah Foto Ber-Geotag</h4>
              <p style={{ margin: 0, color: '#64748b', fontSize: '0.85rem', lineHeight: '1.4' }}>
                Unggah berkas foto JPG/JPEG rumah warga yang diambil dari kamera ber-GPS aktif. Sistem akan menarik metadata lokasi secara otomatis.
              </p>

              <div 
                style={{
                  border: '2px dashed #cbd5e1',
                  borderRadius: '12px',
                  padding: '24px 16px',
                  textAlign: 'center',
                  background: 'rgba(0,0,0,0.02)',
                  cursor: 'pointer',
                  transition: 'border-color 0.2s'
                }}
                onClick={() => fileInputRef.current && fileInputRef.current.click()}
                onMouseOver={(e) => e.currentTarget.style.borderColor = 'var(--success, #10b981)'}
                onMouseOut={(e) => e.currentTarget.style.borderColor = '#cbd5e1'}
              >
                <i className="fas fa-cloud-arrow-up" style={{ fontSize: '2.5rem', color: '#94a3b8', marginBottom: '10px', display: 'block' }}></i>
                <span style={{ fontSize: '0.9rem', color: '#475569', fontWeight: '500' }}>
                  {tempFile ? tempFile.name : 'Klik untuk Pilih Foto Rumah'}
                </span>
                <input 
                  type="file" 
                  ref={fileInputRef} 
                  accept="image/jpeg,image/jpg" 
                  onChange={handleFileChange} 
                  style={{ display: 'none' }} 
                />
              </div>

              {errorMsg && (
                <div style={{ background: '#fee2e2', color: '#ef4444', padding: '12px', borderRadius: '8px', fontSize: '0.8rem', lineHeight: '1.4', fontWeight: '500' }}>
                  <i className="fas fa-exclamation-triangle" style={{ marginRight: '6px' }}></i> {errorMsg}
                </div>
              )}

              {gpsData && (
                <div style={{ background: '#d1fae5', color: '#065f46', padding: '12px', borderRadius: '8px', fontSize: '0.85rem', fontWeight: '500' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '4px' }}>
                    <i className="fas fa-circle-check" style={{ color: '#10b981' }}></i>
                    <strong>Metadata Lokasi Terbaca!</strong>
                  </div>
                  <div style={{ fontSize: '0.75rem', fontFamily: 'monospace', marginTop: '4px', opacity: 0.9 }}>
                    Lintang: {gpsData.lat.toFixed(6)} | Bujur: {gpsData.lng.toFixed(6)}
                  </div>
                </div>
              )}

              <div style={{ display: 'flex', gap: '12px', marginTop: '10px' }}>
                <button
                  type="button"
                  onClick={handleContinueSurvey}
                  disabled={!gpsData}
                  className="btn btn-success"
                  style={{
                    flex: 1, padding: '12px', borderRadius: '10px',
                    fontWeight: '600', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px',
                    opacity: gpsData ? 1 : 0.5, cursor: gpsData ? 'pointer' : 'not-allowed'
                  }}
                >
                  <i className="fas fa-arrow-right"></i> Lanjutkan Pengisian Data
                </button>
              </div>
            </div>
          )}

        </div>
      </div>
    </div>
  );
}
