<?php

namespace App\Imports;

use App\Models\Penduduk;
use App\Models\Dusun; // Import model Dusun
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow; // Untuk membaca header kolom
use Maatwebsite\Excel\Concerns\WithValidation; // Untuk validasi
use Maatwebsite\Excel\Concerns\Importable; // Opsional: untuk Trait Importable
use Illuminate\Validation\Rule; // Untuk rule validasi
use PhpOffice\PhpSpreadsheet\Shared\Date; // Untuk konversi tanggal Excel

class PendudukImport implements ToModel, WithHeadingRow, WithValidation
{
    use Importable; // Memungkinkan penggunaan $import->import()

    /**
     * @param array $row
     *
     * @return \Illuminate\Database\Eloquent\Model|null
     */
    public function model(array $row)
    {
        // Debugging: Anda bisa print_r($row) di sini untuk melihat data yang dibaca dari Excel
        // dd($row);

        // Penting: Pastikan nama kunci array ($row['nik'], $row['nama'], dst.)
        // sesuai dengan nama header di file Excel Anda (case-insensitive berkat WithHeadingRow)

        // Penanganan 'No' dari file export: Kita tidak perlu menyimpannya, jadi kita bisa abaikan.

        // Penanganan NIK: Hapus spasi atau karakter non-digit yang mungkin ditambahkan
        $nik = trim(str_replace("'", "", $row['nik'])); // Hapus apostrof atau spasi jika ada

        // Cari dusun berdasarkan nama, jika tidak ada, validasi akan menangkapnya
        $dusun = Dusun::where('nama', $row['dusun'])->first();

        // Konversi tanggal dari format Excel ke format Carbon/DateTime
        // Maatwebsite/Excel membaca tanggal Excel sebagai angka (float).
        // date_format: 2025-05-30
        $tanggalLahir = null;
        if (isset($row['tanggal_lahir']) && is_numeric($row['tanggal_lahir'])) {
            try {
                $tanggalLahir = Date::excelToDateTimeObject($row['tanggal_lahir'])->format('Y-m-d');
            } catch (\Exception $e) {
                // Log error atau biarkan validasi menangani tanggal yang tidak valid
            }
        } elseif (isset($row['tanggal_lahir'])) {
            // Jika tanggal sudah berupa string (misal dari input manual yang bukan Excel)
            // Coba parse string, pastikan formatnya YYYY-MM-DD
            try {
                $tanggalLahir = \Carbon\Carbon::parse($row['tanggal_lahir'])->format('Y-m-d');
            } catch (\Exception $e) {
                // Biarkan validasi menangani jika parsing gagal
            }
        }


        return new Penduduk([
            'nik' => $nik,
            'nama' => $row['nama'],
            'tempat_lahir' => $row['tempat_lahir'],
            'tanggal_lahir' => $tanggalLahir,
            'jenis_kelamin' => strtolower($row['jenis_kelamin']), // Pastikan lowercase untuk enum
            'alamat' => $row['alamat'],
            'dusun_id' => $dusun->id ?? null, // Atur dusun_id, atau null jika tidak ditemukan
            'rt' => $row['rt'],
            'rw' => $row['rw'],
            'agama' => $row['agama'],
            'perkawinan' => strtolower($row['perkawinan']), // Pastikan lowercase untuk enum
            'pekerjaan' => $row['pekerjaan'],
            'status_penduduk' => strtolower($row['status_penduduk'] ?? 'ada'), // Default ke 'ada' jika tidak ada di Excel
        ]);
    }

    public function rules(): array
    {
        return [
            // '*.nik' => ['required', 'string', 'unique:penduduks,nik'], // Validasi per batch jika pakai WithBatchInserts
            'nik' => ['required', 'string', Rule::unique('penduduk', 'nik')], // Validasi unik per baris
            'nama' => ['required', 'string'],
            'tempat_lahir' => ['required', 'string'],
            // Validasi untuk tanggal_lahir: harus angka (dari Excel) atau string valid format YYYY-MM-DD
            'tanggal_lahir' => [
                'required',
                function ($attribute, $value, $fail) {
                    if (is_numeric($value)) { // Dari Excel
                        try {
                            Date::excelToDateTimeObject($value);
                        } catch (\Exception $e) {
                            $fail('Kolom ' . $attribute . ' memiliki format Excel tanggal yang tidak valid.');
                        }
                    } elseif (is_string($value)) { // Jika string (input manual)
                        if (!preg_match("/^\d{4}-\d{2}-\d{2}$/", $value)) { // Cek format YYYY-MM-DD
                            $fail('Kolom ' . $attribute . ' harus dalam format YYYY-MM-DD atau format tanggal Excel yang valid.');
                        }
                    } else {
                        $fail('Kolom ' . $attribute . ' harus berupa angka atau string tanggal yang valid.');
                    }
                },
            ],
            'jenis_kelamin' => ['required', Rule::in(['laki', 'perempuan'])],
            'alamat' => ['nullable', 'string'],
            // Pastikan 'dusun' ada di tabel 'dusun' pada kolom 'nama'
            'dusun' => ['required', 'string', Rule::exists('dusun', 'nama')],
            'rt' => ['required', 'string'],
            'rw' => ['required', 'string'],
            'agama' => ['nullable', Rule::in(['Islam', 'Kristen Protestan', 'Katolik', 'Hindu', 'Buddha', 'Konghucu'])],
            'perkawinan' => ['required', Rule::in(['sudah', 'belum', 'cerai_mati', 'cerai_hidup'])],
            'pekerjaan' => ['required', 'string'],
            'status_penduduk' => ['nullable', Rule::in(['ada', 'meninggal', 'pindah'])],
        ];
    }

    public function customValidationMessages()
    {
        return [
            'nik.unique' => 'NIK ini sudah terdaftar.',
            'dusun.exists' => 'Dusun tidak ditemukan di database. Pastikan nama dusun di Excel sudah benar.',
            'tanggal_lahir.required' => 'Kolom Tanggal Lahir wajib diisi.',
            'jenis_kelamin.in' => 'Jenis Kelamin harus "laki" atau "perempuan".',
            'perkawinan.in' => 'Status Perkawinan tidak valid.',
            // ... tambahkan pesan kustom lainnya
        ];
    }
}