-- ============================================================
-- SIG Penduduk Miskin v2.0 – Database Schema
-- WebGIS Pendataan & Monitoring Bantuan Sosial
-- Update: 2026 | Versi: 2.0
-- ============================================================

CREATE DATABASE IF NOT EXISTS sig_kemiskinan CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE sig_kemiskinan;

SET FOREIGN_KEY_CHECKS = 0;

-- ============================================================
-- TABEL 1: users
-- ============================================================
CREATE TABLE IF NOT EXISTS users (
    id              INT AUTO_INCREMENT PRIMARY KEY,
    nama            VARCHAR(100) NOT NULL,
    username        VARCHAR(50)  NOT NULL UNIQUE,
    password        VARCHAR(255) NOT NULL COMMENT 'bcrypt hash',
    role            ENUM('admin','petugas','pimpinan') NOT NULL DEFAULT 'petugas',
    wilayah_tugas   VARCHAR(100) NULL COMMENT 'Kelurahan/RT wilayah tugas petugas',
    aktif           TINYINT(1) DEFAULT 1,
    last_login      TIMESTAMP NULL,
    created_at      TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_username (username),
    INDEX idx_role (role)
);

-- ============================================================
-- TABEL 2: wilayah
-- ============================================================
CREATE TABLE IF NOT EXISTS wilayah (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    kelurahan   VARCHAR(100) NOT NULL,
    kecamatan   VARCHAR(100) NOT NULL,
    kota        VARCHAR(100) NOT NULL DEFAULT 'Pontianak',
    rt          VARCHAR(10)  NULL,
    rw          VARCHAR(10)  NULL,
    created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_kelurahan (kelurahan),
    INDEX idx_kecamatan (kecamatan)
);

-- ============================================================
-- TABEL 3: rumah_ibadah (Tidak berubah)
-- ============================================================
CREATE TABLE IF NOT EXISTS rumah_ibadah (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    nama        VARCHAR(255) NOT NULL,
    jenis       ENUM('masjid','musholla','gereja','pura','vihara','klenteng','lainnya') DEFAULT 'masjid',
    alamat      TEXT,
    pic         VARCHAR(255) COMMENT 'Person In Charge / Penanggung Jawab',
    no_wa       VARCHAR(20),
    lat         DECIMAL(10, 8) NOT NULL,
    lng         DECIMAL(11, 8) NOT NULL,
    radius      INT DEFAULT 500 COMMENT 'Radius dalam meter',
    created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- ============================================================
-- TABEL 4: penduduk_miskin (DIPERLUAS dari v1.1)
-- ============================================================
CREATE TABLE IF NOT EXISTS penduduk_miskin (
    id                  INT AUTO_INCREMENT PRIMARY KEY,

    -- Identitas Kepala Keluarga
    nik_kk              VARCHAR(16)   NOT NULL UNIQUE COMMENT 'NIK KK 16 digit',
    nama_kk             VARCHAR(255)  NOT NULL COMMENT 'Nama Kepala Keluarga',
    no_hp               VARCHAR(20)   NULL COMMENT 'No HP/WhatsApp',

    -- Lokasi
    alamat              TEXT          NULL,
    wilayah_id          INT           NULL,
    rt                  VARCHAR(10)   NULL,
    rw                  VARCHAR(10)   NULL,
    lat                 DECIMAL(10,8) NOT NULL,
    lng                 DECIMAL(11,8) NOT NULL,

    -- Data Keluarga
    jumlah_anggota      INT           NOT NULL DEFAULT 1,
    jumlah_anak_sekolah INT           NOT NULL DEFAULT 0,

    -- Data Ekonomi
    penghasilan_bulanan DECIMAL(12,2) NULL COMMENT 'Penghasilan per bulan (Rp)',
    sumber_penghasilan  VARCHAR(255)  NULL,
    status_pekerjaan    ENUM(
        'tidak_bekerja','buruh_harian','petani','nelayan',
        'pedagang','pegawai_swasta','wiraswasta','lainnya'
    ) DEFAULT 'tidak_bekerja',

    -- Kategori Kemiskinan (dihitung otomatis)
    kategori_kemiskinan ENUM('sangat_miskin','miskin','hampir_miskin','mampu') DEFAULT 'sangat_miskin',

    -- Kondisi Rumah
    kondisi_rumah       ENUM('sangat_tidak_layak','tidak_layak','layak') DEFAULT 'tidak_layak',
    kepemilikan_rumah   ENUM('milik_sendiri','kontrak','menumpang','lainnya') DEFAULT 'milik_sendiri',

    -- Status BPJS
    punya_bpjs          TINYINT(1)    DEFAULT 0,
    jenis_bpjs          ENUM('PBI','mandiri','tidak_punya') DEFAULT 'tidak_punya',

    -- Relasi ke Rumah Ibadah (kompatibel v1.1)
    rumah_ibadah_id     INT           NULL,
    jarak_ke_ibadah     DECIMAL(10,2) NULL COMMENT 'Jarak dalam meter',

    -- Status Verifikasi
    status_verifikasi   ENUM('belum_diverifikasi','terverifikasi','ditolak') DEFAULT 'belum_diverifikasi',
    catatan_verifikasi  TEXT          NULL,

    -- Audit Trail
    surveyor_id         INT           NULL COMMENT 'FK users - petugas input',
    verified_by         INT           NULL COMMENT 'FK users - admin verifikator',
    verified_at         TIMESTAMP     NULL,

    created_at          TIMESTAMP     DEFAULT CURRENT_TIMESTAMP,
    updated_at          TIMESTAMP     DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    -- Foreign Keys
    CONSTRAINT fk_pm_wilayah   FOREIGN KEY (wilayah_id)      REFERENCES wilayah(id)       ON DELETE SET NULL,
    CONSTRAINT fk_pm_ibadah    FOREIGN KEY (rumah_ibadah_id) REFERENCES rumah_ibadah(id)  ON DELETE SET NULL,
    CONSTRAINT fk_pm_surveyor  FOREIGN KEY (surveyor_id)     REFERENCES users(id)         ON DELETE SET NULL,
    CONSTRAINT fk_pm_verif     FOREIGN KEY (verified_by)     REFERENCES users(id)         ON DELETE SET NULL,

    INDEX idx_nik       (nik_kk),
    INDEX idx_lat_lng   (lat, lng),
    INDEX idx_kategori  (kategori_kemiskinan),
    INDEX idx_wilayah   (wilayah_id),
    INDEX idx_status_v  (status_verifikasi),
    INDEX idx_surveyor  (surveyor_id)
);

-- ============================================================
-- TABEL 5: foto_rumah
-- ============================================================
CREATE TABLE IF NOT EXISTS foto_rumah (
    id              INT AUTO_INCREMENT PRIMARY KEY,
    penduduk_id     INT           NOT NULL,
    file_path       VARCHAR(500)  NOT NULL COMMENT 'Path relatif dari root web',
    lat_foto        DECIMAL(10,8) NULL COMMENT 'Koordinat GPS saat foto diambil',
    lng_foto        DECIMAL(11,8) NULL,
    accuracy_meter  DECIMAL(8,2)  NULL COMMENT 'Akurasi GPS dalam meter',
    is_primary      TINYINT(1)    DEFAULT 0 COMMENT '1 = foto utama (thumbnail peta)',
    ukuran_kb       INT           NULL,
    keterangan      VARCHAR(255)  NULL,
    diambil_oleh    INT           NULL COMMENT 'FK users',
    created_at      TIMESTAMP     DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT fk_fr_penduduk  FOREIGN KEY (penduduk_id)  REFERENCES penduduk_miskin(id) ON DELETE CASCADE,
    CONSTRAINT fk_fr_user      FOREIGN KEY (diambil_oleh) REFERENCES users(id)           ON DELETE SET NULL,

    INDEX idx_penduduk  (penduduk_id),
    INDEX idx_primary   (penduduk_id, is_primary)
);

-- ============================================================
-- TABEL 6: jenis_bantuan
-- ============================================================
CREATE TABLE IF NOT EXISTS jenis_bantuan (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    kode        VARCHAR(20)  NOT NULL UNIQUE,
    nama        VARCHAR(100) NOT NULL,
    deskripsi   TEXT         NULL,
    warna_badge VARCHAR(7)   DEFAULT '#4f8ef7' COMMENT 'Hex color badge',
    aktif       TINYINT(1)   DEFAULT 1,
    created_at  TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

-- ============================================================
-- TABEL 7: bantuan_penduduk (Many-to-Many pivot)
-- ============================================================
CREATE TABLE IF NOT EXISTS bantuan_penduduk (
    id              INT AUTO_INCREMENT PRIMARY KEY,
    penduduk_id     INT          NOT NULL,
    bantuan_id      INT          NOT NULL,
    status          ENUM('aktif','tidak_aktif','dicabut') DEFAULT 'aktif',
    tanggal_mulai   DATE         NULL,
    tanggal_selesai DATE         NULL,
    nominal_bulanan DECIMAL(12,2) NULL,
    nomor_kpj       VARCHAR(50)  NULL COMMENT 'Nomor kartu/KPJ bantuan',
    keterangan      TEXT         NULL,
    diinput_oleh    INT          NULL COMMENT 'FK users',
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    CONSTRAINT fk_bp_penduduk  FOREIGN KEY (penduduk_id)  REFERENCES penduduk_miskin(id) ON DELETE CASCADE,
    CONSTRAINT fk_bp_bantuan   FOREIGN KEY (bantuan_id)   REFERENCES jenis_bantuan(id)   ON DELETE RESTRICT,
    CONSTRAINT fk_bp_user      FOREIGN KEY (diinput_oleh) REFERENCES users(id)           ON DELETE SET NULL,

    UNIQUE KEY uq_penduduk_bantuan (penduduk_id, bantuan_id),
    INDEX idx_penduduk  (penduduk_id),
    INDEX idx_bantuan   (bantuan_id),
    INDEX idx_status    (status)
);

-- ============================================================
-- TABEL 8: riwayat_verifikasi (Audit Trail)
-- ============================================================
CREATE TABLE IF NOT EXISTS riwayat_verifikasi (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    penduduk_id INT          NOT NULL,
    user_id     INT          NOT NULL,
    aksi        ENUM('submit','verifikasi','tolak','update','hapus') NOT NULL,
    catatan     TEXT         NULL,
    data_lama   JSON         NULL COMMENT 'Snapshot data sebelum perubahan',
    created_at  TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT fk_rv_penduduk FOREIGN KEY (penduduk_id) REFERENCES penduduk_miskin(id) ON DELETE CASCADE,
    CONSTRAINT fk_rv_user     FOREIGN KEY (user_id)     REFERENCES users(id)           ON DELETE RESTRICT,

    INDEX idx_penduduk  (penduduk_id),
    INDEX idx_user      (user_id),
    INDEX idx_tanggal   (created_at)
);

-- ============================================================
-- TABEL 9: notifikasi
-- ============================================================
CREATE TABLE IF NOT EXISTS notifikasi (
    id              INT AUTO_INCREMENT PRIMARY KEY,
    user_id         INT          NULL COMMENT 'NULL = broadcast semua admin',
    jenis           ENUM('belum_bantuan','belum_verifikasi','data_usang','info') DEFAULT 'info',
    judul           VARCHAR(255) NOT NULL,
    pesan           TEXT         NOT NULL,
    penduduk_id     INT          NULL COMMENT 'Referensi penduduk terkait',
    sudah_dibaca    TINYINT(1)   DEFAULT 0,
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT fk_notif_user     FOREIGN KEY (user_id)     REFERENCES users(id)           ON DELETE CASCADE,
    CONSTRAINT fk_notif_penduduk FOREIGN KEY (penduduk_id) REFERENCES penduduk_miskin(id) ON DELETE SET NULL,

    INDEX idx_user_baca (user_id, sudah_dibaca),
    INDEX idx_jenis     (jenis)
);

-- ============================================================
-- INDEX SPASIAL
-- ============================================================
CREATE INDEX idx_ri_lat_lng ON rumah_ibadah(lat, lng);

SET FOREIGN_KEY_CHECKS = 1;

-- ============================================================
-- DATA AWAL: users
-- ============================================================
INSERT INTO users (nama, username, password, role) VALUES
('Administrator',   'admin',    '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin'),
('Petugas Survei',  'petugas',  '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'petugas'),
('Kepala Dinas',    'pimpinan', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'pimpinan');
-- [REDACTED](bcrypt)

-- ============================================================
-- DATA AWAL: wilayah
-- ============================================================
INSERT INTO wilayah (kelurahan, kecamatan, kota, rt, rw) VALUES
('Siantan Tengah',  'Pontianak Utara',  'Pontianak', '01', '01'),
('Siantan Tengah',  'Pontianak Utara',  'Pontianak', '02', '01'),
('Siantan Hilir',   'Pontianak Utara',  'Pontianak', '01', '02'),
('Batu Layang',     'Pontianak Utara',  'Pontianak', '01', '01'),
('Batu Layang',     'Pontianak Utara',  'Pontianak', '02', '02'),
('Saigon',          'Pontianak Timur',  'Pontianak', '01', '01'),
('Saigon',          'Pontianak Timur',  'Pontianak', '02', '01'),
('Tanjung Hulu',    'Pontianak Timur',  'Pontianak', '01', '01'),
('Parit Mayor',     'Pontianak Timur',  'Pontianak', '01', '01'),
('Pontianak Kota',  'Pontianak Kota',   'Pontianak', '01', '01');

-- ============================================================
-- DATA AWAL: rumah_ibadah
-- ============================================================
INSERT INTO rumah_ibadah (nama, jenis, alamat, pic, no_wa, lat, lng, radius) VALUES
('Masjid Al-Ikhlas',  'masjid', 'Jl. Merdeka No. 1, Pontianak',      'Ahmad Fauzi',    '081234567890', -0.0263303, 109.3425094, 500),
('Masjid Ar-Rahmat',  'masjid', 'Jl. Gajah Mada No. 45, Pontianak',  'Budi Santoso',   '082345678901', -0.0320000, 109.3380000, 500),
('Gereja Bethel',     'gereja', 'Jl. Diponegoro No. 12, Pontianak',   'Pendeta Yusuf',  '083456789012', -0.0290000, 109.3450000, 500);

-- ============================================================
-- DATA AWAL: jenis_bantuan
-- ============================================================
INSERT INTO jenis_bantuan (kode, nama, deskripsi, warna_badge) VALUES
('PKH',  'Program Keluarga Harapan',  'Bantuan tunai bersyarat untuk KK miskin',         '#22c55e'),
('BPNT', 'Bantuan Pangan Non Tunai',  'Sembako via e-warong setiap 2 bulan',             '#3b82f6'),
('KIS',  'Kartu Indonesia Sehat',     'Akses layanan kesehatan gratis (BPJS PBI)',        '#ec4899'),
('BLT',  'Bantuan Langsung Tunai',    'Bantuan tunai darurat/sementara dari desa/kel',   '#f59e0b'),
('BST',  'Bantuan Sosial Tunai',      'Bantuan sosial tunai dari Kemensos',              '#8b5cf6'),
('PIP',  'Program Indonesia Pintar',  'Bantuan pendidikan untuk anak sekolah',           '#06b6d4');

-- ============================================================
-- DATA AWAL: penduduk_miskin (contoh)
-- ============================================================
INSERT INTO penduduk_miskin (
    nik_kk, nama_kk, no_hp, alamat, wilayah_id, rt, rw,
    lat, lng, jumlah_anggota, jumlah_anak_sekolah,
    penghasilan_bulanan, sumber_penghasilan, status_pekerjaan,
    kategori_kemiskinan, kondisi_rumah, kepemilikan_rumah,
    punya_bpjs, jenis_bpjs, status_verifikasi, surveyor_id
) VALUES
('6171010101010001', 'Suyatno',       '081200000001', 'Jl. Merdeka Gg. III No. 5',    1, '01', '01', -0.0270000, 109.3430000, 4, 2, 850000,  'Buruh bangunan',   'buruh_harian',  'miskin',         'tidak_layak',       'menumpang',     1, 'PBI',       'terverifikasi',    1),
('6171010101010002', 'Rohani',        '081200000002', 'Jl. Merdeka Gg. IV No. 2',     1, '02', '01', -0.0255000, 109.3420000, 3, 1, 450000,  'Jualan kecil',     'pedagang',      'sangat_miskin',  'sangat_tidak_layak','menumpang',     1, 'PBI',       'terverifikasi',    1),
('6171010101010003', 'Hamid Husin',   '081200000003', 'Jl. Gajah Mada Gg. II No. 8', 2, '01', '02', -0.0315000, 109.3375000, 5, 3, 1200000, 'Ojek online',      'buruh_harian',  'mampu',          'tidak_layak',       'kontrak',       0, 'tidak_punya','belum_diverifikasi',2),
('6171010101010004', 'Yanti Susanti', '081200000004', 'Jl. Veteran No. 99',           3, '01', '01', -0.0500000, 109.3600000, 2, 0, 300000,  'Tidak ada',        'tidak_bekerja', 'sangat_miskin',  'sangat_tidak_layak','menumpang',     1, 'PBI',       'terverifikasi',    1),
('6171010101010005', 'Supriyadi',     '081200000005', 'Jl. Budi Utomo No. 12',        4, '02', '01', -0.0340000, 109.3510000, 6, 4, 600000,  'Petani kecil',     'petani',        'miskin',         'tidak_layak',       'milik_sendiri', 1, 'PBI',       'terverifikasi',    1),
('6171010101010006', 'Marlina',       '081200000006', 'Gg. Damai No. 3',              5, '01', '02', -0.0410000, 109.3480000, 3, 1, 200000,  'Buruh cuci',       'buruh_harian',  'sangat_miskin',  'sangat_tidak_layak','menumpang',     0, 'tidak_punya','belum_diverifikasi',2),
('6171010101010007', 'Junaidi',       '081200000007', 'Jl. Khatulistiwa No. 45',      6, '01', '01', -0.0380000, 109.3550000, 4, 2, 950000,  'Nelayan',          'nelayan',       'miskin',         'tidak_layak',       'milik_sendiri', 1, 'mandiri',   'terverifikasi',    1),
('6171010101010008', 'Siti Aminah',   '081200000008', 'Gg. Melati No. 7',             7, '02', '02', -0.0290000, 109.3395000, 5, 3, 400000,  'Pembantu RT',      'buruh_harian',  'sangat_miskin',  'sangat_tidak_layak','menumpang',     1, 'PBI',       'belum_diverifikasi',2),
('6171010101010009', 'Rahman',        '081200000009', 'Jl. Tanjung Pura No. 88',      8, '01', '01', -0.0220000, 109.3460000, 3, 1, 750000,  'Pedagang kaki lima','pedagang',     'miskin',         'tidak_layak',       'kontrak',       0, 'tidak_punya','terverifikasi',    1),
('6171010101010010', 'Dewi Kartika',  '081200000010', 'Gg. Bahagia No. 2',            9, '01', '01', -0.0450000, 109.3530000, 4, 2, 500000,  'Buruh pabrik',     'buruh_harian',  'sangat_miskin',  'tidak_layak',       'kontrak',       1, 'PBI',       'terverifikasi',    1);

-- ============================================================
-- DATA AWAL: bantuan_penduduk
-- ============================================================
INSERT INTO bantuan_penduduk (penduduk_id, bantuan_id, status, tanggal_mulai, nominal_bulanan, diinput_oleh) VALUES
(1, 1, 'aktif', '2024-01-01', 500000, 1),   -- Suyatno: PKH
(1, 2, 'aktif', '2024-01-01', 200000, 1),   -- Suyatno: BPNT
(2, 1, 'aktif', '2023-07-01', 500000, 1),   -- Rohani: PKH
(2, 3, 'aktif', '2023-07-01', 0,      1),   -- Rohani: KIS
(4, 1, 'aktif', '2024-03-01', 500000, 1),   -- Yanti: PKH
(4, 3, 'aktif', '2024-03-01', 0,      1),   -- Yanti: KIS
(5, 2, 'aktif', '2024-02-01', 200000, 1),   -- Supriyadi: BPNT
(7, 3, 'aktif', '2023-09-01', 0,      1),   -- Junaidi: KIS
(9, 2, 'aktif', '2024-01-01', 200000, 1),   -- Rahman: BPNT
(10, 1, 'aktif','2024-04-01', 500000, 1),   -- Dewi: PKH
(10, 3, 'aktif','2024-04-01', 0,      1);   -- Dewi: KIS

-- ============================================================
-- Update rumah_ibadah assignment (kompatibel v1.1)
-- ============================================================
UPDATE penduduk_miskin pm
SET
    rumah_ibadah_id = (
        SELECT ri.id FROM rumah_ibadah ri
        WHERE (
            6371000 * ACOS(GREATEST(-1, LEAST(1,
                COS(RADIANS(pm.lat)) * COS(RADIANS(ri.lat)) *
                COS(RADIANS(ri.lng) - RADIANS(pm.lng)) +
                SIN(RADIANS(pm.lat)) * SIN(RADIANS(ri.lat))
            )))
        ) <= ri.radius
        ORDER BY (
            6371000 * ACOS(GREATEST(-1, LEAST(1,
                COS(RADIANS(pm.lat)) * COS(RADIANS(ri.lat)) *
                COS(RADIANS(ri.lng) - RADIANS(pm.lng)) +
                SIN(RADIANS(pm.lat)) * SIN(RADIANS(ri.lat))
            )))
        ) ASC
        LIMIT 1
    ),
    jarak_ke_ibadah = (
        SELECT ROUND(
            6371000 * ACOS(GREATEST(-1, LEAST(1,
                COS(RADIANS(pm.lat)) * COS(RADIANS(ri.lat)) *
                COS(RADIANS(ri.lng) - RADIANS(pm.lng)) +
                SIN(RADIANS(pm.lat)) * SIN(RADIANS(ri.lat))
            ))), 2
        ) FROM rumah_ibadah ri
        WHERE (
            6371000 * ACOS(GREATEST(-1, LEAST(1,
                COS(RADIANS(pm.lat)) * COS(RADIANS(ri.lat)) *
                COS(RADIANS(ri.lng) - RADIANS(pm.lng)) +
                SIN(RADIANS(pm.lat)) * SIN(RADIANS(ri.lat))
            )))
        ) <= ri.radius
        LIMIT 1
    );
