<?php

namespace App\Services;

use App\Models\Participant;
use App\Models\Program;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use League\Csv\Reader;

class ParticipantImportService
{
    public function import(Program $program, UploadedFile $file, ?string $defaultSession): array
    {
        $result = ['success' => 0, 'duplicates' => 0, 'failed' => 0, 'errors' => []];

        $csv = Reader::createFromPath($file->getRealPath(), 'r');
        $csv->setHeaderOffset(0);

        // Strip UTF-8 BOM if present (Excel-exported CSV)
        $csv->setOutputBOM('');
        try {
            $csv->addStreamFilter('convert.iconv.UTF-8/UTF-8');
        } catch (\Throwable) {}

        foreach ($csv->getRecords() as $rowNum => $row) {
            $row = array_map('trim', $row);

            // Normalise header keys (lowercase, strip BOM)
            $row = array_combine(
                array_map(fn($k) => strtolower(preg_replace('/[\x{FEFF}\s]/u', '', $k)), array_keys($row)),
                array_values($row)
            );

            $data = [
                'name'   => $row['name']   ?? $row['nama']   ?? '',
                'no_kp'  => preg_replace('/[^0-9]/', '', $row['no_kp'] ?? $row['nokp'] ?? $row['ic'] ?? ''),
                'email'  => $row['email']  ?? $row['emel']   ?? null,
                'phone'  => $row['phone']  ?? $row['telefon'] ?? $row['phone'] ?? null,
                'agency' => $row['agency'] ?? $row['agensi'] ?? $row['jabatan'] ?? null,
            ];

            // Validate row
            $validator = Validator::make($data, [
                'name'  => ['required', 'string', 'max:255'],
                'no_kp' => ['required', 'digits:12'],
                'email' => ['nullable', 'email', 'max:255'],
                'phone' => ['nullable', 'string', 'max:20'],
            ]);

            if ($validator->fails()) {
                $result['failed']++;
                $result['errors'][] = 'Baris ' . ($rowNum + 2) . ': ' . implode(', ', $validator->errors()->all());
                continue;
            }

            try {
                DB::transaction(function () use ($program, $data, $defaultSession, &$result) {
                    // Find or create participant by no_kp
                    $participant = Participant::firstOrCreate(
                        ['no_kp' => $data['no_kp']],
                        [
                            'name'             => $data['name'],
                            'email'            => $data['email'] ?: null,
                            'phone'            => $data['phone'] ?: null,
                            'agency'           => $data['agency'] ?: null,
                            'participant_type' => 'staff',
                        ]
                    );

                    // Check duplicate in this program
                    $exists = $program->programParticipants()
                                      ->where('participant_id', $participant->id)
                                      ->exists();

                    if ($exists) {
                        $result['duplicates']++;
                        return;
                    }

                    $program->programParticipants()->create([
                        'participant_id'         => $participant->id,
                        'registration_source'    => 'import',
                        'is_pre_registered'      => true,
                        'pre_registered_session' => $defaultSession,
                        'status'                 => 'registered',
                        'registered_at'          => now(),
                    ]);

                    $result['success']++;
                });
            } catch (\Throwable $e) {
                $result['failed']++;
                $result['errors'][] = 'Baris ' . ($rowNum + 2) . ': Ralat sistem — ' . $e->getMessage();
            }
        }

        return $result;
    }
}
