<?php

namespace App\Services\Import\Handlers;

use App\Models\Import;
use App\Models\Person\PersonPhone;
use App\Services\Import\BaseEntityHandler;

class PhoneHandler extends BaseEntityHandler
{
    public function getEntityClass(): string
    {
        return PersonPhone::class;
    }

    /**
     * Override validate to skip validation if phone is empty.
     * Handles both single values and arrays.
     */
    public function validate(array $mapped): array
    {
        $phone = $mapped['nu'] ?? null;
        
        // If array, check if all values are empty/invalid
        if (is_array($phone)) {
            $hasValue = false;
            foreach ($phone as $ph) {
                if (!empty($ph) && trim((string)$ph) !== '' && $ph !== '0') {
                    $hasValue = true;
                    break;
                }
            }
            if (!$hasValue) {
                return ['valid' => true, 'errors' => []];
            }
            // Skip parent validation for arrays - we'll validate in process()
            return ['valid' => true, 'errors' => []];
        }
        
        // Single value - check if empty or invalid
        if (empty($phone) || trim((string)$phone) === '' || $phone === '0') {
            return ['valid' => true, 'errors' => []];
        }

        return parent::validate($mapped);
    }

    public function resolve(array $mapped, array $context = []): mixed
    {
        $nu = $mapped['nu'] ?? null;
        $personId = $mapped['person_id'] 
            ?? ($context['person']['entity']->id ?? null)
            ?? ($context['person']?->entity?->id ?? null);

        if (! $nu || ! $personId) {
            return null;
        }

        // Normalize phone number for comparison
        $normalizedNu = $this->normalizePhoneNumber($nu);

        // Find existing phone by normalized number for this person
        return PersonPhone::where('person_id', $personId)
            ->where('nu', $normalizedNu)
            ->first();
    }

    public function process(Import $import, array $mapped, array $raw, array $context = []): array
    {
        // Handle multiple phones if nu is an array
        $phones = $mapped['nu'] ?? null;
        
        // If single value, convert to array for uniform processing
        if (!is_array($phones)) {
            $phones = [$phones];
        }
        
        $results = [];
        $insertedCount = 0;
        $skippedCount = 0;
        
        foreach ($phones as $phone) {
            // Skip if phone number is empty or blank or '0'
            if (empty($phone) || trim((string)$phone) === '' || $phone === '0') {
                $skippedCount++;
                continue;
            }
            
            // Resolve person_id from context
            $personId = $mapped['person_id'] ?? $context['person']['entity']?->id ?? null;

            if (! $personId) {
                $skippedCount++;
                continue;
            }

            // Normalize phone number
            $normalizedPhone = $this->normalizePhoneNumber($phone);

            $existing = $this->resolvePhone($normalizedPhone, $personId);

            // Check for duplicates if configured
            if ($this->getOption('deduplicate', true) && $existing) {
                $skippedCount++;
                continue;
            }

            // Create new phone
            $payload = [
                'nu' => $normalizedPhone,
                'person_id' => $personId,
                'type_id' => 1, // Default to mobile
            ];

            $phoneEntity = new PersonPhone;
            $phoneEntity->fill($payload);
            $phoneEntity->save();
            
            $results[] = $phoneEntity;
            $insertedCount++;
        }
        
        if ($insertedCount === 0 && $skippedCount > 0) {
            return [
                'action' => 'skipped',
                'message' => 'All phones empty, invalid or duplicates',
            ];
        }
        
        return [
            'action' => 'inserted',
            'entity' => $results[0] ?? null,
            'entities' => $results,
            'applied_fields' => ['nu', 'person_id'],
            'count' => $insertedCount,
        ];
    }
    
    protected function resolvePhone(string $normalizedPhone, int $personId): mixed
    {
        return PersonPhone::where('person_id', $personId)
            ->where('nu', $normalizedPhone)
            ->first();
    }

    /**
     * Normalize phone number by removing spaces, dashes, and parentheses.
     */
    protected function normalizePhoneNumber(string $phone): string
    {
        return preg_replace('/[\s\-\(\)]/', '', $phone);
    }
}
