<?php

/*
 * File ini bagian dari:
 *
 * OpenDK
 *
 * Aplikasi dan source code ini dirilis berdasarkan lisensi GPL V3
 *
 * Hak Cipta 2017 - 2024 Perkumpulan Desa Digital Terbuka (https://opendesa.id)
 *
 * Dengan ini diberikan izin, secara gratis, kepada siapa pun yang mendapatkan salinan
 * dari perangkat lunak ini dan file dokumentasi terkait ("Aplikasi Ini"), untuk diperlakukan
 * tanpa batasan, termasuk hak untuk menggunakan, menyalin, mengubah dan/atau mendistribusikan,
 * asal tunduk pada syarat berikut:
 *
 * Pemberitahuan hak cipta di atas dan pemberitahuan izin ini harus disertakan dalam
 * setiap salinan atau bagian penting Aplikasi Ini. Barang siapa yang menghapus atau menghilangkan
 * pemberitahuan ini melanggar ketentuan lisensi Aplikasi Ini.
 *
 * PERANGKAT LUNAK INI DISEDIAKAN "SEBAGAIMANA ADANYA", TANPA JAMINAN APA PUN, BAIK TERSURAT MAUPUN
 * TERSIRAT. PENULIS ATAU PEMEGANG HAK CIPTA SAMA SEKALI TIDAK BERTANGGUNG JAWAB ATAS KLAIM, KERUSAKAN ATAU
 * KEWAJIBAN APAPUN ATAS PENGGUNAAN ATAU LAINNYA TERKAIT APLIKASI INI.
 *
 * @package    OpenDK
 * @author     Tim Pengembang OpenDesa
 * @copyright  Hak Cipta 2017 - 2024 Perkumpulan Desa Digital Terbuka (https://opendesa.id)
 * @license    http://www.gnu.org/licenses/gpl.html    GPL V3
 * @link       https://github.com/OpenSID/opendk
 */

namespace Database\Seeders;

use App\Models\User;
use App\Models\Role;
use App\Models\Permission;
use Illuminate\Database\Seeder;

class RoleSpatieSeeder extends Seeder
{
    /**
     * Daftar aksi yang tersedia per modul (level 3 permission).
     * Format: 'nama_permission_modul' => ['aksi1', 'aksi2', ...]
     */
    protected array $moduleActions = [
        // Informasi
        'access.informasi.prosedur'         => ['view', 'create', 'edit', 'delete', 'export'],
        'access.informasi.regulasi'         => ['view', 'create', 'edit', 'delete', 'export'],
        'access.informasi.potensi'          => ['view', 'create', 'edit', 'delete'],
        'access.informasi.event'            => ['view', 'create', 'edit', 'delete'],
        'access.informasi.artikel'          => ['view', 'create', 'edit', 'delete'],
        'access.informasi.artikel_kategori' => ['view', 'create', 'edit', 'delete'],
        'access.informasi.komentar_artikel' => ['view', 'edit', 'delete'],
        'access.informasi.faq'              => ['view', 'create', 'edit', 'delete'],
        'access.informasi.form_dokumen'     => ['view', 'create', 'edit', 'delete'],
        'access.informasi.media_sosial'     => ['view', 'create', 'edit', 'delete'],
        'access.informasi.media_terkait'    => ['view', 'create', 'edit', 'delete'],
        'access.informasi.sinergi_program'  => ['view', 'create', 'edit', 'delete'],
        // Publikasi
        'access.publikasi.album'            => ['view', 'create', 'edit', 'delete'],
        'access.publikasi.galeri'           => ['view', 'create', 'edit', 'delete'],
        // Data
        'access.data.profil'                => ['view', 'edit'],
        'access.data.data_umum'             => ['view', 'edit'],
        'access.data.data_desa'             => ['view', 'create', 'edit', 'delete', 'export'],
        'access.data.data_sarana'           => ['view', 'create', 'edit', 'delete', 'export', 'import'],
        'access.data.jabatan'               => ['view', 'create', 'edit', 'delete'],
        'access.data.pengurus'              => ['view', 'create', 'edit', 'delete'],
        'access.data.penduduk'              => ['view', 'export', 'import'],
        'access.data.keluarga'              => ['view', 'export'],
        'access.data.data_suplemen'         => ['view', 'create', 'edit', 'delete', 'export'],
        'access.data.laporan_penduduk'      => ['view', 'delete', 'export', 'import'],
        'access.data.aki_akb'               => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.imunisasi'             => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.epidemi_penyakit'      => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.toilet_sanitasi'       => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.tingkat_pendidikan'    => ['view', 'delete', 'export', 'import'],
        'access.data.putus_sekolah'         => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.fasilitas_paud'        => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.program_bantuan'       => ['view', 'export', 'import'],
        'access.data.anggaran_realisasi'    => ['view', 'edit', 'delete', 'export', 'import'],
        'access.data.anggaran_desa'         => ['view', 'delete', 'export', 'import'],
        'access.data.laporan_apbdes'        => ['view', 'delete', 'export', 'import'],
        'access.data.pembangunan'           => ['view', 'export'],
        'access.data.kategori_lembaga'      => ['view', 'create', 'edit', 'delete'],
        'access.data.lembaga'               => ['view', 'create', 'edit', 'delete'],
        // Admin Komplain
        'access.admin_komplain'             => ['view', 'edit', 'delete'],
        // Setting
        'access.setting.user'               => ['view', 'create', 'edit', 'delete'],
        'access.setting.role'               => ['view', 'create', 'edit', 'delete'],
        'access.setting.slide'              => ['view', 'create', 'edit', 'delete'],
        'access.setting.widget'             => ['view', 'edit'],
        'access.setting.nav_menu'           => ['view', 'create', 'edit', 'delete'],
        'access.setting.navigation'         => ['view', 'create', 'edit', 'delete'],
        'access.setting.komplain_kategori'  => ['view', 'create', 'edit', 'delete'],
        'access.setting.tipe_regulasi'      => ['view', 'create', 'edit', 'delete'],
        'access.setting.jenis_penyakit'     => ['view', 'create', 'edit', 'delete'],
        'access.setting.tipe_potensi'       => ['view', 'create', 'edit', 'delete'],
        'access.setting.coa'                => ['view', 'create', 'edit', 'delete'],
        'access.setting.themes'             => ['view', 'edit'],
        'access.setting.aplikasi'           => ['view', 'edit'],
        'access.setting.info_sistem'        => ['view'],
        'access.setting.database'           => ['view', 'export', 'import'],
        'access.setting.jenis_dokumen'      => ['view', 'create', 'edit', 'delete'],
    ];

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        // =====================================================================
        // FASE 1: Permission Level 1 & 2 (per modul)
        // =====================================================================
        // Catatan: access.counter, access.change_default, dan access.api dihapus
        // karena tidak relevan untuk manajemen hak akses group pengguna.
        $permissions = [
            'access.dashboard',
            'access.informasi',
            'access.informasi.prosedur',
            'access.informasi.regulasi',
            'access.informasi.potensi',
            'access.informasi.event',
            'access.informasi.artikel',
            'access.informasi.artikel_kategori',
            'access.informasi.komentar_artikel',
            'access.informasi.faq',
            'access.informasi.form_dokumen',
            'access.informasi.media_sosial',
            'access.informasi.media_terkait',
            'access.informasi.sinergi_program',
            'access.publikasi',
            'access.publikasi.album',
            'access.publikasi.galeri',
            'access.kerjasama',
            'access.data',
            'access.data.profil',
            'access.data.data_umum',
            'access.data.data_desa',
            'access.data.data_sarana',
            'access.data.jabatan',
            'access.data.pengurus',
            'access.data.penduduk',
            'access.data.keluarga',
            'access.data.data_suplemen',
            'access.data.laporan_penduduk',
            'access.data.aki_akb',
            'access.data.imunisasi',
            'access.data.epidemi_penyakit',
            'access.data.toilet_sanitasi',
            'access.data.tingkat_pendidikan',
            'access.data.putus_sekolah',
            'access.data.fasilitas_paud',
            'access.data.program_bantuan',
            'access.data.anggaran_realisasi',
            'access.data.anggaran_desa',
            'access.data.laporan_apbdes',
            'access.data.pembangunan',
            'access.data.kategori_lembaga',
            'access.data.lembaga',
            'access.admin_komplain',
            'access.pesan',
            'access.surat',
            'access.setting',
            'access.setting.user',
            'access.setting.role',
            'access.setting.widget',
            'access.setting.nav_menu',
            'access.setting.navigation',
            'access.setting.komplain_kategori',
            'access.setting.tipe_regulasi',
            'access.setting.jenis_penyakit',
            'access.setting.tipe_potensi',
            'access.setting.slide',
            'access.setting.coa',
            'access.setting.themes',
            'access.setting.aplikasi',
            'access.setting.info_sistem',
            'access.setting.database',
            'access.setting.jenis_dokumen',
        ];

        $sort = 1;
        foreach ($permissions as $name) {
            Permission::updateOrCreate(['name' => $name, 'guard_name' => 'web'], [
                'name'       => $name,
                'slug'       => $name,
                'parent_id'  => 0,
                'sort'       => $sort++,
                'guard_name' => 'web',
            ]);
        }

        // =====================================================================
        // FASE 2: Permission Level 3 (aksi per modul)
        // =====================================================================
        foreach ($this->moduleActions as $moduleName => $actions) {
            // Ambil permission parent (level 2 atau level 1 untuk admin_komplain)
            $parentPermission = Permission::where('name', $moduleName)
                ->where('guard_name', 'web')
                ->first();

            if (! $parentPermission) {
                continue;
            }

            foreach ($actions as $action) {
                $actionName = "{$moduleName}.{$action}";
                Permission::updateOrCreate(
                    ['name' => $actionName, 'guard_name' => 'web'],
                    [
                        'name'       => $actionName,
                        'slug'       => $actionName,
                        'parent_id'  => $parentPermission->id,
                        'sort'       => $sort++,
                        'guard_name' => 'web',
                    ]
                );
            }
        }

        // Refresh cache setelah buat semua permission
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        // =====================================================================
        // FASE 3: Roles
        // =====================================================================
        $superAdmin           = Role::firstOrCreate(['name' => 'super-admin', 'guard_name' => 'web']);
        $adminKecamatan       = Role::firstOrCreate(['name' => 'admin-kecamatan', 'guard_name' => 'web']);
        $adminKomplain        = Role::firstOrCreate(['name' => 'admin-komplain', 'guard_name' => 'web']);
        $administratorWebsite = Role::firstOrCreate(['name' => 'administrator-website', 'guard_name' => 'web']);

        // Super-admin mendapat semua permission (level 1, 2, dan 3)
        $allPermissions = Permission::where('guard_name', 'web')->pluck('name')->toArray();
        $superAdmin->syncPermissions($allPermissions);

        // Admin Kecamatan: semua permission kecuali access.setting.*
        $adminKecamatanPermissions = array_values(array_filter($allPermissions, function ($permission) {
            return ! str_starts_with($permission, 'access.setting');
        }));
        $adminKecamatan->syncPermissions($adminKecamatanPermissions);

        // Admin Komplain: hanya akses Admin Komplain dan Pengaturan Kategori Komplain
        $adminKomplainPermissions = array_filter([
            'access.dashboard',
            'access.admin_komplain',
            'access.admin_komplain.view',
            'access.admin_komplain.edit',
            'access.admin_komplain.delete',
            'access.setting',
            'access.setting.komplain_kategori',
            'access.setting.komplain_kategori.view',
            'access.setting.komplain_kategori.create',
            'access.setting.komplain_kategori.edit',
            'access.setting.komplain_kategori.delete',
        ], fn($p) => Permission::where('name', $p)->where('guard_name', 'web')->exists());
        $adminKomplain->syncPermissions($adminKomplainPermissions);

        // Administrator Website: akses Informasi, Publikasi, dan Pengaturan Slide
        $administratorWebsitePermissions = array_filter([
            'access.dashboard',
            // Informasi — semua sub-modul
            'access.informasi',
            'access.informasi.prosedur',
            'access.informasi.prosedur.view',
            'access.informasi.prosedur.create',
            'access.informasi.prosedur.edit',
            'access.informasi.prosedur.delete',
            'access.informasi.prosedur.export',
            'access.informasi.regulasi',
            'access.informasi.regulasi.view',
            'access.informasi.regulasi.create',
            'access.informasi.regulasi.edit',
            'access.informasi.regulasi.delete',
            'access.informasi.regulasi.export',
            'access.informasi.potensi',
            'access.informasi.potensi.view',
            'access.informasi.potensi.create',
            'access.informasi.potensi.edit',
            'access.informasi.potensi.delete',
            'access.informasi.event',
            'access.informasi.event.view',
            'access.informasi.event.create',
            'access.informasi.event.edit',
            'access.informasi.event.delete',
            'access.informasi.artikel',
            'access.informasi.artikel.view',
            'access.informasi.artikel.create',
            'access.informasi.artikel.edit',
            'access.informasi.artikel.delete',
            'access.informasi.artikel_kategori',
            'access.informasi.artikel_kategori.view',
            'access.informasi.artikel_kategori.create',
            'access.informasi.artikel_kategori.edit',
            'access.informasi.artikel_kategori.delete',
            'access.informasi.komentar_artikel',
            'access.informasi.komentar_artikel.view',
            'access.informasi.komentar_artikel.edit',
            'access.informasi.komentar_artikel.delete',
            'access.informasi.faq',
            'access.informasi.faq.view',
            'access.informasi.faq.create',
            'access.informasi.faq.edit',
            'access.informasi.faq.delete',
            'access.informasi.form_dokumen',
            'access.informasi.form_dokumen.view',
            'access.informasi.form_dokumen.create',
            'access.informasi.form_dokumen.edit',
            'access.informasi.form_dokumen.delete',
            'access.informasi.media_sosial',
            'access.informasi.media_sosial.view',
            'access.informasi.media_sosial.create',
            'access.informasi.media_sosial.edit',
            'access.informasi.media_sosial.delete',
            'access.informasi.media_terkait',
            'access.informasi.media_terkait.view',
            'access.informasi.media_terkait.create',
            'access.informasi.media_terkait.edit',
            'access.informasi.media_terkait.delete',
            'access.informasi.sinergi_program',
            'access.informasi.sinergi_program.view',
            'access.informasi.sinergi_program.create',
            'access.informasi.sinergi_program.edit',
            'access.informasi.sinergi_program.delete',
            // Publikasi — semua sub-modul
            'access.publikasi',
            'access.publikasi.album',
            'access.publikasi.album.view',
            'access.publikasi.album.create',
            'access.publikasi.album.edit',
            'access.publikasi.album.delete',
            'access.publikasi.galeri',
            'access.publikasi.galeri.view',
            'access.publikasi.galeri.create',
            'access.publikasi.galeri.edit',
            'access.publikasi.galeri.delete',
            // Pengaturan Slide
            'access.setting',
            'access.setting.slide',
            'access.setting.slide.view',
            'access.setting.slide.create',
            'access.setting.slide.edit',
            'access.setting.slide.delete',
        ], fn($p) => Permission::where('name', $p)->where('guard_name', 'web')->exists());
        $administratorWebsite->syncPermissions($administratorWebsitePermissions);

        // =====================================================================
        // FASE 4: User admin default
        // =====================================================================
        $user = User::where('email', 'admin@mail.com')->first();

        if ($user === null) {
            $admin = User::create([
                'email'    => 'admin@mail.com',
                'name'     => 'Administrator',
                'gender'   => 'Male',
                'address'  => 'Jakarta',
                'status'   => 1,
                'password' => bcrypt('password'),
            ]);
            $admin->assignRole($superAdmin);
        } else {
            $user->syncRoles([$superAdmin->name]);
        }
    }
}
