<?php

namespace App\Http\Controllers;

use App\Models\ImportEntity;
use Illuminate\Http\Request;

class ImportEntityController extends Controller
{
    public function index()
    {
        $entities = ImportEntity::query()
            ->orderByRaw("(ui->>'order')::int nulls last")
            ->get();

        // Fallback: if no entities are seeded yet, return a sensible default set
        if ($entities->isEmpty()) {
            $entities = collect([
                [
                    'key' => 'person',
                    'canonical_root' => 'person',
                    'label' => 'Person',
                    'fields' => ['first_name', 'last_name', 'full_name', 'gender', 'birthday', 'tax_number', 'social_security_number', 'description'],
                    'ui' => ['order' => 1],
                ],
                [
                    'key' => 'person_addresses',
                    'canonical_root' => 'address',
                    'label' => 'Person Addresses',
                    'fields' => ['address', 'country', 'type_id', 'description'],
                    'ui' => ['order' => 2],
                ],
                [
                    'key' => 'person_phones',
                    'canonical_root' => 'phone',
                    'label' => 'Person Phones',
                    'fields' => ['nu', 'country_code', 'type_id', 'description'],
                    'ui' => ['order' => 3],
                ],
                [
                    'key' => 'emails',
                    'canonical_root' => 'email',
                    'label' => 'Emails',
                    'fields' => ['value', 'is_primary', 'label'],
                    'ui' => ['order' => 4],
                ],
                [
                    'key' => 'contracts',
                    'canonical_root' => 'contract',
                    'label' => 'Contracts',
                    'fields' => ['reference', 'start_date', 'end_date', 'description', 'type_id', 'client_case_id'],
                    'ui' => ['order' => 5],
                ],
                [
                    'key' => 'accounts',
                    'canonical_root' => 'account',
                    'label' => 'Accounts',
                    'fields' => ['reference', 'balance_amount', 'contract_id', 'contract_reference', 'type_id', 'active', 'description'],
                    'ui' => ['order' => 6],
                ],
                [
                    'key' => 'activities',
                    'canonical_root' => 'activity',
                    'label' => 'Activities',
                    'fields' => ['note', 'due_date', 'amount', 'action_id', 'decision_id', 'contract_id', 'client_case_id', 'user_id'],
                    'ui' => ['order' => 7],
                ],
            ]);
        } else {
            // Ensure fields are arrays for frontend consumption
            $entities = $entities->map(function ($ent) {
                $ent->fields = is_array($ent->fields) ? $ent->fields : [];

                return $ent;
            });
        }

        return response()->json(['entities' => $entities]);
    }

    public function suggest(Request $request)
    {
        $cols = $request->input('columns', []);
        if (! is_array($cols)) {
            $cols = [];
        }
        // Optional filter: only suggest for specific entity keys (e.g., template meta.entities)
        $only = $request->input('only_entities');
        $query = ImportEntity::query()->orderByRaw("(ui->>'order')::int nulls last");
        if (is_array($only) && ! empty($only)) {
            $query->whereIn('key', array_values(array_filter($only, fn ($v) => is_string($v) && $v !== '')));
        }
        $entities = $query->get();
        $suggestions = [];
        foreach ($cols as $col) {
            $s = $this->suggestFor($col, $entities);
            if ($s) {
                $suggestions[$col] = $s;
            }
        }

        return response()->json(['suggestions' => $suggestions]);
    }

    private function suggestFor(string $source, $entities): ?array
    {
        $s = trim(mb_strtolower($source));
        $best = null;
        $bestRank = PHP_INT_MAX;
        foreach ($entities as $ent) {
            $rules = (array) ($ent->rules ?? []);
            foreach ($rules as $rule) {
                $pattern = $rule['pattern'] ?? null;
                $field = $rule['field'] ?? null;
                if (! $pattern || ! $field) {
                    continue;
                }
                if (@preg_match($pattern, $s)) {
                    // Rank preferences: payments over address for amount/date-like terms
                    $rank = (int) ($ent->ui['order'] ?? 999);
                    $isPayment = ($ent->canonical_root ?? null) === 'payment';
                    $isAddress = ($ent->canonical_root ?? null) === 'address';
                    if ($isPayment) {
                        $rank -= 10; // boost payments
                    } elseif ($isAddress && in_array($field, ['amount', 'payment_date', 'payment_nu', 'reference'])) {
                        $rank += 10; // demote addresses for these
                    }
                    if ($rank < $bestRank) {
                        $bestRank = $rank;
                        $best = [
                            'entity' => $ent->key,
                            'field' => $field,
                            'canonical_root' => $ent->canonical_root,
                        ];
                    }
                }
            }
        }

        return $best;
    }
}
