<?php

namespace App\Http\Controllers;

use App\Models\Masjid;
use App\Models\PenerimaanZakat;
use App\Models\DistribusiZakat;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class PublikController extends Controller
{
    /**
     * Halaman Depan Utama: Menampilkan Rekap Global & Daftar Masjid
     * Data diambil dari tabel PenerimaanZakat (bukan Muzakki yang sudah tidak ada)
     */
    public function index()
    {
        // --- LOGIKA TRANSPARANSI GLOBAL ---
        // 1. Menghitung total penerimaan zakat uang dari seluruh masjid
        $total_uang = PenerimaanZakat::where('jenis_zakat', 'uang')->sum('total_bayar');

        // 2. Menghitung total penerimaan zakat beras dari seluruh masjid
        $total_beras = PenerimaanZakat::where('jenis_zakat', 'beras')->sum('total_bayar');

        // 3. Menghitung total transaksi penerimaan zakat (jumlah muzakki)
        $jumlah_muzakki = PenerimaanZakat::count();

        // 4. Menghitung total distribusi zakat yang sudah disalurkan
        $total_distribusi = DistribusiZakat::where('status_terima', 'sudah')->sum('jumlah_distribusi');

        // Mengambil semua daftar masjid agar bisa dipilih masyarakat
        $semua_masjid = Masjid::all();

        // Kirim data rekap ke view landing_page
        return view('landing_page', compact(
            'total_uang',
            'total_beras',
            'jumlah_muzakki',
            'total_distribusi',
            'semua_masjid'
        ));
    }

    /**
     * Halaman Detail Masjid: Rekap penerimaan & distribusi per masjid
     * Menggunakan id_masjid (bukan slug, karena kolom slug tidak ada di tabel)
     */
    public function detailMasjid($id)
    {
        $masjid = Masjid::findOrFail($id);

        // --- LOGIKA TRANSPARANSI PER MASJID ---
        $rekap_uang = PenerimaanZakat::where('id_masjid', $masjid->id_masjid)
            ->where('jenis_zakat', 'uang')
            ->sum('total_bayar');

        $rekap_beras = PenerimaanZakat::where('id_masjid', $masjid->id_masjid)
            ->where('jenis_zakat', 'beras')
            ->sum('total_bayar');

        $rekap_distribusi = DistribusiZakat::where('id_masjid', $masjid->id_masjid)
            ->where('status_terima', 'sudah')
            ->sum('jumlah_distribusi');

        return view('detail_masjid', compact('masjid', 'rekap_uang', 'rekap_beras', 'rekap_distribusi'));
    }

    /**
     * Cek Status Zakat: Warga bisa cek apakah sudah bayar zakat
     * Mencari berdasarkan nama penyetor di PenerimaanZakat
     */
    public function cekZakat(Request $request, $id)
    {
        $masjid = Masjid::findOrFail($id);
        $keyword = $request->query('keyword');
        $hasil = null;

        if ($keyword) {
            // Cari berdasarkan nama penyetor atau atas nama
            $hasil = PenerimaanZakat::where('id_masjid', $masjid->id_masjid)
                ->where(function ($query) use ($keyword) {
                    $query->where('nama_penyetor', 'like', '%' . $keyword . '%')
                          ->orWhere('atas_name', 'like', '%' . $keyword . '%');
                })
                ->get();
        }

        return view('cek_zakat', compact('masjid', 'hasil', 'keyword'));
    }

    /**
     * Cetak Kuitansi: Menampilkan kuitansi pembayaran zakat
     */
    public function cetakKuitansi($id)
    {
        $data = PenerimaanZakat::with('masjid', 'petugas')->findOrFail($id);
        return view('kuitansi_pdf', compact('data'));
    }

    /**
     * Proxy Geocoding — Geoapify Autocomplete API (3.000 req/hari gratis)
     * Fallback ke Nominatim jika API key belum dikonfigurasi.
     * Request dari SERVER → API key aman, tidak terekspos ke browser.
     */
    public function geocode(Request $request)
    {
        $query  = trim($request->query('q', ''));
        $apiKey = config('services.geoapify.key', env('GEOAPIFY_API_KEY', ''));

        if (!$query) {
            return response()->json(['results' => [], 'error' => 'Query kosong'], 400);
        }

        // Gunakan Geoapify jika API key sudah diisi
        if ($apiKey && $apiKey !== 'ISI_API_KEY_GEOAPIFY_ANDA_DI_SINI') {
            $results = $this->callGeoapify($query, $apiKey);
            
            // Cek apakah hasil Geocoding valid menemukan bangunan masjid
            $foundMosque = false;
            foreach ($results as $r) {
                if (stripos($r['name'], 'masjid') !== false || stripos($r['name'], 'mushola') !== false) {
                    $foundMosque = true;
                    break;
                }
            }

            // Fallback ke Geoapify Places API jika:
            // 1. Hasil kosong ATAU tidak menemukan spesifik kata 'masjid'
            // 2. Dan query dari user mengandung niat mencari 'masjid'
            if (!$foundMosque && (stripos($query, 'masjid') !== false || stripos($query, 'mushola') !== false)) {
                $placesResults = $this->callGeoapifyPlaces($query, $apiKey);
                
                // Gabungkan hasil (Places ditaruh paling atas)
                if (!empty($placesResults)) {
                    $results = array_merge($placesResults, $results);
                }
            }

            if (!empty($results)) {
                // Batasi max 7
                return response()->json(['results' => array_slice($results, 0, 7)]);
            }
        }

        // Fallback: Nominatim (multi-varian) → Photon
        $variants = $this->buatVarianQuery($query);
        $results  = [];
        foreach ($variants as $variant) {
            if (!$variant) continue;
            $results = $this->callNominatim($variant);
            if (!empty($results)) break;
        }
        if (empty($results)) {
            $simplest = end($variants) ?: $query;
            $results  = $this->callPhoton($simplest);
        }

        return response()->json(['results' => $results]);
    }

    /**
     * Geoapify Geocoding Autocomplete
     * Docs: https://apidocs.geoapify.com/docs/geocoding/address-autocomplete/
     */
    private function callGeoapify(string $query, string $apiKey): array
    {
        try {
            $res = Http::timeout(8)->get('https://api.geoapify.com/v1/geocode/autocomplete', [
                'text'   => $query,
                'apiKey' => $apiKey,
                'lang'   => 'id',
                'limit'  => 5,
                'filter' => 'countrycode:id',
                'format' => 'json',
            ]);

            if (!$res->successful()) return [];
            $results = $res->json()['results'] ?? [];
            if (empty($results)) return [];

            $out = [];
            foreach ($results as $item) {
                $lat = $item['lat'] ?? null;
                $lng = $item['lon'] ?? null;
                if (!$lat || !$lng) continue;

                $name = $item['name'] ?? $item['address_line1'] ?? $item['formatted'] ?? 'Lokasi';
                $detail = $item['formatted'] ?? $item['address_line2'] ?? '';

                $out[] = [
                    'name'   => $name,
                    'detail' => $detail,
                    'lat'    => (float) $lat,
                    'lng'    => (float) $lng,
                ];
            }
            return $out;
        } catch (\Throwable $e) {
            return [];
        }
    }

    /**
     * Geoapify Places API (Pencarian Bangunan Spesifik / POI)
     * Kategori: religion.place_of_worship
     */
    private function callGeoapifyPlaces(string $query, string $apiKey): array
    {
        try {
            // Ekstrak nama masjid (2-4 kata pertama) agar Places API akurat
            // cth: "Masjid Jami Al Ihsan Pondok Petir" -> "Masjid Jami Al Ihsan"
            $nameFilter = $query;
            if (preg_match('/^(Masjid(?:\s+Jami)?(?:\s+[A-Za-z0-9\-]+){1,2})/i', $query, $m)) {
                $nameFilter = trim($m[1]);
            }

            $res = Http::timeout(8)->get('https://api.geoapify.com/v2/places', [
                'categories' => 'religion.place_of_worship',
                'filter'     => 'rect:95.0,-11.0,141.0,6.0', // Bounding box Indonesia
                'name'       => $nameFilter,
                'limit'      => 5,
                'apiKey'     => $apiKey,
            ]);

            if (!$res->successful()) return [];
            $features = $res->json()['features'] ?? [];
            if (empty($features)) return [];

            $out = [];
            foreach ($features as $f) {
                $p = $f['properties'];
                $coords = $f['geometry']['coordinates'] ?? [null, null];
                $lat = $coords[1];
                $lng = $coords[0];

                if (!$lat || !$lng) continue;

                $out[] = [
                    'name'   => $p['name'] ?? 'Tempat Ibadah',
                    'detail' => $p['formatted'] ?? '',
                    'lat'    => (float) $lat,
                    'lng'    => (float) $lng,
                ];
            }
            return $out;
        } catch (\Throwable $e) {
            return [];
        }
    }

    // -------------------------------------------------------
    // Fallback methods (Nominatim & Photon) — tetap dipakai
    // jika Geoapify belum dikonfigurasi
    // -------------------------------------------------------

    private function buatVarianQuery(string $query): array
    {
        $variants   = [$query];
        $stripped   = trim(preg_replace('/\s+/', ' ', preg_replace([
            '/\bJl\.?\s+/i', '/\bNo\.?\s*\d+\w*\s*/i',
            '/\bRT\.?\s*\d+\s*(\/\s*RW\.?\s*\d+)?\s*/i', '/\bRW\.?\s*\d+\s*/i',
        ], ' ', $query)));

        $kel = $kec = $kota = null;
        if (preg_match('/\bKel\.?\s+([^,.]+)/i',          $query, $m)) $kel  = trim($m[1]);
        if (preg_match('/\bKec\.?\s+([^,.]+)/i',          $query, $m)) $kec  = trim($m[1]);
        if (preg_match('/\b(?:Kota|Kab\.?)\s+([^,.]+)/i', $query, $m)) $kota = trim($m[1]);

        if (!$kota) {
            $words = preg_split('/\s+/', $stripped);
            $kota  = count($words) >= 2
                ? implode(' ', array_slice($words, -2))
                : ($words[0] ?? null);
        }

        if ($v = implode(' ', array_filter([$kel, $kec, $kota]))) $variants[] = $v;
        if ($v = implode(' ', array_filter([$kec, $kota])))        $variants[] = $v;
        if ($kota) $variants[] = $kota;

        return array_unique(array_filter($variants));
    }

    private function callNominatim(string $query): array
    {
        try {
            $res = Http::timeout(8)
                ->withHeaders([
                    'User-Agent'      => 'ZakatMasjidApp/1.0 (skripsi@student.ac.id)',
                    'Accept-Language' => 'id,en;q=0.5',
                    'Referer'         => url('/'),
                ])
                ->get('https://nominatim.openstreetmap.org/search', [
                    'format' => 'json', 'q' => $query,
                    'countrycodes' => 'id', 'limit' => 5, 'addressdetails' => 1,
                ]);
            if (!$res->successful()) return [];
            return array_map(fn($i) => [
                'name'   => $i['name'] ?? explode(',', $i['display_name'])[0],
                'detail' => $i['display_name'],
                'lat'    => (float) $i['lat'],
                'lng'    => (float) $i['lon'],
            ], $res->json() ?? []);
        } catch (\Throwable $e) { return []; }
    }

    private function callPhoton(string $query): array
    {
        try {
            $res = Http::timeout(8)->get('https://photon.komoot.io/api/', [
                'q' => $query, 'lang' => 'id', 'limit' => 5,
                'bbox' => '95.0,-11.0,141.0,6.0',
            ]);
            if (!$res->successful()) return [];
            $out = [];
            foreach ($res->json()['features'] ?? [] as $f) {
                if (!str_contains(strtolower($f['properties']['country'] ?? ''), 'indonesia')) continue;
                $p = $f['properties'];
                $parts = array_filter([$p['name'] ?? null, $p['street'] ?? null, $p['city'] ?? null, $p['state'] ?? null]);
                $out[] = [
                    'name'   => $p['name'] ?? (reset($parts) ?: 'Lokasi'),
                    'detail' => implode(', ', $parts) . (isset($p['country']) ? ', '.$p['country'] : ''),
                    'lat'    => $f['geometry']['coordinates'][1],
                    'lng'    => $f['geometry']['coordinates'][0],
                ];
            }
            return $out;
        } catch (\Throwable $e) { return []; }
    }
}
