<?php

namespace App\Services;

use App\Models\Attendance;
use App\Models\Participant;
use App\Models\Program;
use App\Models\ProgramParticipant;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AttendanceService
{
    public function staffCheckin(Program $program, string $noKp, Request $request): array
    {
        $noKp = preg_replace('/[^0-9]/', '', $noKp);

        // Find participant
        $participant = Participant::where('no_kp', $noKp)->first();
        if (! $participant) {
            return ['status' => 'not_found'];
        }

        // Check if registered in this program
        $pp = ProgramParticipant::where('program_id', $program->id)
                                 ->where('participant_id', $participant->id)
                                 ->first();

        if (! $pp) {
            return ['status' => 'not_registered', 'participant' => $participant];
        }

        // Already checked in
        if (Attendance::where('program_id', $program->id)->where('participant_id', $participant->id)->exists()) {
            $att = Attendance::where('program_id', $program->id)->where('participant_id', $participant->id)->first();
            return ['status' => 'already_checked_in', 'participant' => $participant, 'attendance' => $att];
        }

        // Record attendance
        $attendance = DB::transaction(function () use ($program, $participant, $pp, $request) {
            $session = $pp->pre_registered_session ?? $program->default_staff_session ?? 'full_day';

            // Kemaskini emel/telefon peserta jika diisi semasa check-in
            $contactUpdate = array_filter([
                'email' => $request->filled('email') ? $request->input('email') : null,
                'phone' => $request->filled('phone') ? $request->input('phone') : null,
            ]);
            if ($contactUpdate) {
                $participant->update($contactUpdate);
            }

            $pp->update(['status' => 'checked_in']);

            return Attendance::create([
                'program_id'          => $program->id,
                'participant_id'      => $participant->id,
                'program_participant_id' => $pp->id,
                'attendance_source'   => 'pre_registered_staff',
                'attendance_session'  => $session,
                'checked_in_at'       => now(),
                'checked_in_ip'       => $request->ip(),
                'user_agent'          => substr($request->userAgent() ?? '', 0, 500),
            ]);
        });

        return ['status' => 'success', 'participant' => $participant, 'attendance' => $attendance];
    }

    public function walkInRegister(Program $program, array $data, Request $request): array
    {
        $noKp = preg_replace('/[^0-9]/', '', $data['no_kp']);

        // Check duplicate in this program
        $existing = Participant::where('no_kp', $noKp)->first();
        if ($existing) {
            $alreadyRegistered = ProgramParticipant::where('program_id', $program->id)
                                                    ->where('participant_id', $existing->id)
                                                    ->exists();
            if ($alreadyRegistered) {
                // Check if already attended
                $att = Attendance::where('program_id', $program->id)
                                  ->where('participant_id', $existing->id)
                                  ->first();
                if ($att) {
                    return ['status' => 'already_checked_in', 'participant' => $existing, 'attendance' => $att];
                }
            }
        }

        $result = DB::transaction(function () use ($program, $data, $noKp, $existing, $request) {
            $participant = $existing ?? Participant::create([
                'name'             => $data['name'],
                'no_kp'            => $noKp,
                'email'            => $data['email'] ?: null,
                'phone'            => $data['phone'] ?: null,
                'agency'           => $data['agency'] ?: null,
                'participant_type' => 'external',
            ]);

            // Create program_participant if not exists
            $pp = ProgramParticipant::firstOrCreate(
                ['program_id' => $program->id, 'participant_id' => $participant->id],
                [
                    'registration_source'   => 'walk_in',
                    'is_pre_registered'     => false,
                    'pre_registered_session'=> $program->default_external_session,
                    'status'                => 'registered',
                    'registered_at'         => now(),
                ]
            );

            $session = $program->default_external_session ?? 'full_day';

            $pp->update(['status' => 'checked_in']);

            $attendance = Attendance::create([
                'program_id'             => $program->id,
                'participant_id'         => $participant->id,
                'program_participant_id' => $pp->id,
                'attendance_source'      => 'walk_in_external',
                'attendance_session'     => $session,
                'checked_in_at'          => now(),
                'checked_in_ip'          => $request->ip(),
                'user_agent'             => substr($request->userAgent() ?? '', 0, 500),
            ]);

            return ['status' => 'success', 'participant' => $participant, 'attendance' => $attendance];
        });

        return $result;
    }
}
