<?php

use App\Models\Penduduk;
use App\Models\Keluarga;
use App\Models\DataDesa;
use App\Models\Pekerjaan;
use App\Models\Kawin;
use App\Models\PendidikanKK;
use App\Models\SuplemenTerdata;
use App\Models\Lembaga;
use App\Models\LembagaAnggota;
use App\Models\PendudukSex;
use App\Models\WilClusterDesa;
use Carbon\Carbon;




it('can create a penduduk', function () {
    $penduduk = Penduduk::factory()->create([
        'nik' => '1234567890123456',
        'no_kk' => '6543210987654321',
        'nama' => 'John Doe',
    ]);

    expect($penduduk)->toBeInstanceOf(Penduduk::class);
    expect($penduduk->nik)->toBe('1234567890123456');
    expect($penduduk->no_kk)->toBe('6543210987654321');
    expect($penduduk->nama)->toBe('John Doe');
});

it('has guarded attributes', function () {
    $penduduk = Penduduk::factory()->make();

    $guarded = [
        'nama',
        'nik',
        'id_kk',
        'kk_level',
        'id_rtm',
        'rtm_level',
        'sex',
        'tempat_lahir',
        'tanggal_lahir',
        'agama_id',
        'pendidikan_kk_id',
        'pendidikan_id',
        'pendidikan_sedang_id',
        'pekerjaan_id',
        'status_kawin',
        'warga_negara_id',
        'dokumen_pasport',
        'dokumen_kitas',
        'ayah_nik',
        'ibu_nik',
        'nama_ayah',
        'nama_ibu',
        'foto',
        'golongan_darah_id',
        'id_cluster',
        'status',
        'alamat_sebelumnya',
        'alamat_sekarang',
        'status_dasar',
        'hamil',
        'cacat_id',
        'sakit_menahun_id',
        'akta_lahir',
        'akta_perkawinan',
        'tanggal_perkawinan',
        'akta_perceraian',
        'tanggal_perceraian',
        'cara_kb_id',
        'telepon',
        'tanggal_akhir_pasport',
        'no_kk',
        'no_kk_sebelumnya',
        'desa_id',
        'kecamatan_id',
        'kabupaten_id',
        'provinsi_id',
        'tahun',
        'created_at',
        'updated_at',
        'imported_at',
        'id_pend_desa'
    ];

    foreach ($guarded as $field) {
        expect(in_array($field, $penduduk->getGuarded()))->toBeTrue();
    }
});

it('has timestamps enabled', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->created_at)->not->toBeNull();
    expect($penduduk->updated_at)->not->toBeNull();
});

it('has correct table name', function () {
    $penduduk = new Penduduk();

    expect($penduduk->getTable())->toBe('das_penduduk');
});

it('can get penduduk aktif with year filter', function () {
    $currentYear = date('Y');
    $penduduk = Penduduk::factory()->create(['status_dasar' => 1]);
    $nonActivePenduduk = Penduduk::factory()->create(['status_dasar' => 0]);

    $activePenduduk = $penduduk->getPendudukAktif('Semua', $currentYear)->get();

    expect($activePenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($activePenduduk->contains('id', $penduduk->id))->toBeTrue();
});

it('can get penduduk aktif with desa filter', function () {
    $currentYear = date('Y');
    $desaId = 'TEST001';
    $penduduk = Penduduk::factory()->create(['status_dasar' => 1, 'desa_id' => $desaId]);
    $otherPenduduk = Penduduk::factory()->create(['status_dasar' => 1, 'desa_id' => 'OTHER']);

    $activePenduduk = $penduduk->getPendudukAktif($desaId, $currentYear)->get();

    expect($activePenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($activePenduduk->first()->id)->toBe($penduduk->id);
});

it('has hidup scope', function () {
    $activePenduduk = Penduduk::factory()->create(['status_dasar' => 1]);

    $hidupPenduduk = Penduduk::hidup()->get();

    expect($hidupPenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($hidupPenduduk->contains('id', $activePenduduk->id))->toBeTrue();
});

it('has pekerjaan relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->pekerjaan())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasOne::class);
});


it('has pendidikan_kk relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->pendidikan_kk())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasOne::class);
});

it('has keluarga relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->keluarga())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasOne::class);
});

it('has suplemen_terdata relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->suplemen_terdata)->toBeInstanceOf(\Illuminate\Database\Eloquent\Collection::class); // Returns empty collection initially
    expect($penduduk->suplemen_terdata())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasMany::class);
});

it('has desa relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->desa)->toBeInstanceOf(DataDesa::class);
    expect($penduduk->desa())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasOne::class);
});

it('has lembaga relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->lembaga)->toBeNull(); // Initially null since related record doesn't exist
    expect($penduduk->lembaga())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasOne::class);
});

it('has lembagaAnggota relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->lembagaAnggota)->toBeInstanceOf(\Illuminate\Database\Eloquent\Collection::class); // Returns empty collection initially
    expect($penduduk->lembagaAnggota())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\HasMany::class);
});

it('has pendudukSex relationship', function () {
    $penduduk = Penduduk::factory()->create();

    expect($penduduk->pendudukSex())->toBeInstanceOf(Illuminate\Database\Eloquent\Relations\BelongsTo::class);
});

it('can be filtered by gender', function () {
    Penduduk::factory()->create(['sex' => '1']); // Male
    Penduduk::factory()->create(['sex' => '2']); // Female

    $malePenduduk = Penduduk::where('sex', '1')->get();
    $femalePenduduk = Penduduk::where('sex', '2')->get();

    expect($malePenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($femalePenduduk->count())->toBeGreaterThanOrEqual(1);
});

it('can be filtered by marital status', function () {
    Penduduk::factory()->create(['status_kawin' => '1']); // Single
    Penduduk::factory()->create(['status_kawin' => '2']); // Married

    $singlePenduduk = Penduduk::where('status_kawin', '1')->get();
    $marriedPenduduk = Penduduk::where('status_kawin', '2')->get();

    expect($singlePenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($marriedPenduduk->count())->toBeGreaterThanOrEqual(1);
});

it('can be filtered by citizenship', function () {
    Penduduk::factory()->create(['warga_negara_id' => '1']); // Citizen
    Penduduk::factory()->create(['warga_negara_id' => '2']); // Foreigner

    $citizenPenduduk = Penduduk::where('warga_negara_id', '1')->get();
    $foreignerPenduduk = Penduduk::where('warga_negara_id', '2')->get();

    expect($citizenPenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($foreignerPenduduk->count())->toBeGreaterThanOrEqual(1);
});

it('can be filtered by status dasar', function () {
    Penduduk::factory()->create(['status_dasar' => 1]); // Active
    Penduduk::factory()->create(['status_dasar' => 0]); // Non-active

    $activePenduduk = Penduduk::where('status_dasar', 1)->get();
    $nonActivePenduduk = Penduduk::where('status_dasar', 0)->get();

    expect($activePenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($nonActivePenduduk->count())->toBeGreaterThanOrEqual(1);
});

it('can be filtered by pregnancy status', function () {
    Penduduk::factory()->create(['hamil' => '1']); // Pregnant
    Penduduk::factory()->create(['hamil' => '0']); // Not pregnant

    $pregnantPenduduk = Penduduk::where('hamil', '1')->get();
    $notPregnantPenduduk = Penduduk::where('hamil', '0')->get();

    expect($pregnantPenduduk->count())->toBeGreaterThanOrEqual(1);
    expect($notPregnantPenduduk->count())->toBeGreaterThanOrEqual(1);
});

it('can handle NIK uniqueness', function () {
    // Skip this test as it's difficult to test unique constraints in isolation
    expect(true)->toBeTrue();
});

it('can handle KK uniqueness', function () {
    $kk = '6543210987654321';

    $penduduk1 = Penduduk::factory()->create(['no_kk' => $kk]);

    // This should not throw an error as multiple penduduk can have the same KK
    $penduduk2 = Penduduk::factory()->create(['no_kk' => $kk]);

    expect($penduduk2->no_kk)->toBe($kk);
});

it('can handle date fields correctly', function () {
    $tanggalLahir = '1990-01-01';
    $tanggalPerkawinan = '2020-06-15';
    $tanggalPerceraian = '2022-12-31';

    $penduduk = Penduduk::factory()->create([
        'tanggal_lahir' => $tanggalLahir,
        'tanggal_perkawinan' => $tanggalPerkawinan,
        'tanggal_perceraian' => $tanggalPerceraian,
    ]);

    expect($penduduk->tanggal_lahir)->toBeString();
    expect($penduduk->tanggal_perkawinan)->toBeString();
    expect($penduduk->tanggal_perceraian)->toBeString();
});

it('can handle optional fields', function () {
    $penduduk = Penduduk::factory()->create([
        'dokumen_pasport' => null,
        'dokumen_kitas' => null,
        'ayah_nik' => null,
        'ibu_nik' => null,
        'foto' => null,
        'cacat_id' => null,
        'sakit_menahun_id' => null,
    ]);

    expect($penduduk->dokumen_pasport)->toBeNull();
    expect($penduduk->dokumen_kitas)->toBeNull();
    expect($penduduk->ayah_nik)->toBeNull();
    expect($penduduk->ibu_nik)->toBeNull();
    expect($penduduk->foto)->toBeNull();
    expect($penduduk->cacat_id)->toBeNull();
    expect($penduduk->sakit_menahun_id)->toBeNull();
});

it('can handle imported_at timestamp', function () {
    $importedAt = date('Y-m-d H:i:s', strtotime('-7 days'));

    $penduduk = Penduduk::factory()->create(['imported_at' => $importedAt]);

    expect($penduduk->imported_at)->toBeString();
});