import { createClient } from '@supabase/supabase-js';
import { NextResponse } from 'next/server';
import kecamatanData from '@/lib/Admin_Kecamatan.json';

const isPointInPolygon = (point, polygon) => {
  const x = point[0], y = point[1];
  let inside = false;
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i][0], yi = polygon[i][1];
    const xj = polygon[j][0], yj = polygon[j][1];
    const intersect = ((yi > y) !== (yj > y))
        && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
    if (intersect) inside = !inside;
  }
  return inside;
};

const getKecamatanForPoint = (lat, lng) => {
  if (!kecamatanData || !kecamatanData.features) return null;
  for (const feature of kecamatanData.features) {
    const name = feature.properties?.Ket;
    const geom = feature.geometry;
    if (!name || !geom) continue;

    if (geom.type === 'Polygon') {
      if (isPointInPolygon([lng, lat], geom.coordinates[0])) {
        return name;
      }
    } else if (geom.type === 'MultiPolygon') {
      for (const polygonCoords of geom.coordinates) {
        if (isPointInPolygon([lng, lat], polygonCoords[0])) {
          return name;
        }
      }
    }
  }
  return null;
};

const parseLocation = (loc) => {
  if (!loc) return { lat: 0, lng: 0 };
  if (typeof loc === 'string') {
    const match = loc.match(/POINT\(([^ ]+) ([^ ]+)\)/);
    if (match) return { lng: parseFloat(match[1]), lat: parseFloat(match[2]) };
  } else if (loc.coordinates) {
    return { lng: loc.coordinates[0], lat: loc.coordinates[1] };
  }
  return { lat: 0, lng: 0 };
};

// Calculate distance in meters between two points (Haversine formula approximation equivalent to Leaflet's distance)
const distanceTo = (lat1, lon1, lat2, lon2) => {
  const R = 6371e3; // metres
  const φ1 = lat1 * Math.PI/180; // φ, λ in radians
  const φ2 = lat2 * Math.PI/180;
  const Δφ = (lat2-lat1) * Math.PI/180;
  const Δλ = (lon2-lon1) * 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; 
};

export async function GET() {
  try {
    const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
    const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;

    if (!supabaseServiceKey) {
      return NextResponse.json({ error: 'Service role key not configured' }, { status: 500 });
    }

    const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey);

    // Fetch all hubs and households using admin privileges
    const { data: hubsData, error: hubsErr } = await supabaseAdmin.from('hubs').select('*');
    const { data: hhData, error: hhErr } = await supabaseAdmin.from('households').select('*');

    if (hubsErr) throw hubsErr;
    if (hhErr) throw hhErr;

    const parsedHubs = (hubsData || []).map(hub => {
      const { lat, lng } = parseLocation(hub.location);
      return { ...hub, lat, lng, radius: hub.radius_meter };
    });

    let coveredCount = 0;
    const typeCounts = {};
    const subDistrictsMap = {};
    const subDistrictsList = ['Pontianak Barat', 'Pontianak Kota', 'Pontianak Selatan', 'Pontianak Tenggara', 'Pontianak Timur', 'Pontianak Utara'];
    
    subDistrictsList.forEach(sub => {
      subDistrictsMap[sub] = { covered: 0, uncovered: 0 };
    });

    (hhData || []).forEach((hh, idx) => {
      const { lat, lng } = parseLocation(hh.location);
      
      let closestHub = null;
      let minDistance = Infinity;

      parsedHubs.forEach(hub => {
        const dist = distanceTo(lat, lng, hub.lat, hub.lng);
        const hubRadius = parseInt(hub.radius) || 500;
        if (dist <= hubRadius && dist < minDistance) {
          minDistance = dist;
          closestHub = hub;
        }
      });

      const covered = !!closestHub;
      if (covered) {
        coveredCount++;
        const type = closestHub.type;
        typeCounts[type] = (typeCounts[type] || 0) + 1;
      }

      // Sub-district logic (now provided by PostGIS database trigger with dynamic backend JS fallback!)
      let sub = hh.sub_district;
      if (!sub || sub === 'Belum Terpetakan') {
        const coords = parseLocation(hh.location);
        sub = getKecamatanForPoint(coords.lat, coords.lng) || 'Belum Terpetakan';
      }
      
      if (!subDistrictsMap[sub]) subDistrictsMap[sub] = { covered: 0, uncovered: 0 };
      
      if (covered) subDistrictsMap[sub].covered++;
      else subDistrictsMap[sub].uncovered++;
    });

    const total = hhData ? hhData.length : 0;
    const uncoveredCount = total - coveredCount;
    const equalityIndex = total > 0 ? Math.round((coveredCount / total) * 100) : 0;

    return NextResponse.json({
      hubsCount: parsedHubs.length,
      coveredCount,
      uncoveredCount,
      equalityIndex,
      subDistrictsMap,
      typeCounts
    });

  } catch (error) {
    console.error('Stats API Error:', error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}
