<?php

declare(strict_types=1);

require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/contract_form.php';
require_once __DIR__ . '/local_store.php';

function admin_delete_password_required(): bool
{
    return !empty(app_config()['require_delete_password']);
}

function admin_action_password_valid(string $password): bool
{
    if (!admin_delete_password_required()) {
        return true;
    }

    $stored = (string)(app_config()['admin_action_password'] ?? '');

    if ($stored === '' || $password === '') {
        return false;
    }

    return password_verify($password, $stored);
}

function contract_delete_related_files(string $token, array $contract, array $signatures): void
{
    $config = app_config();
    $token = trim($token);

    if ($token === '') {
        return;
    }

    $paths = [];

    if (contract_pdf_available($contract)) {
        $paths[] = contract_pdf_path($contract);
    } else {
        $fallback = $config['contracts_dir'] . '/' . $token . '.pdf';
        if (is_file($fallback)) {
            $paths[] = $fallback;
        }
    }

    if (contract_signed_pdf_available($contract)) {
        $paths[] = contract_signed_pdf_path($contract);
    } else {
        $fallback = $config['signed_dir'] . '/' . $token . '_signed.pdf';
        if (is_file($fallback)) {
            $paths[] = $fallback;
        }
    }

    foreach ($signatures as $signature) {
        $image = basename((string)($signature['signature_image'] ?? ''));
        if ($image !== '') {
            $paths[] = $config['signatures_dir'] . '/' . $image;
        }
    }

    foreach (glob($config['signatures_dir'] . '/' . $token . '_*') ?: [] as $file) {
        $paths[] = $file;
    }

    foreach (glob($config['contracts_dir'] . '/*' . $token . '*') ?: [] as $file) {
        $paths[] = $file;
    }

    foreach (glob($config['signed_dir'] . '/*' . $token . '*') ?: [] as $file) {
        $paths[] = $file;
    }

    foreach (array_unique($paths) as $path) {
        if (is_file($path)) {
            @unlink($path);
        }
    }
}

function contract_brands_from_record(array $contract): array
{
    if (!empty($contract['brands']) && is_array($contract['brands'])) {
        return array_values(array_filter($contract['brands'], static fn($b): bool => trim((string)$b) !== ''));
    }

    $allowed = ['Gulab', 'Flamers'];
    $selected = [];

    foreach (explode(',', (string)($contract['brand'] ?? '')) as $part) {
        $part = trim($part);
        if ($part === 'Flamers Pizza') {
            $part = 'Flamers';
        }
        if (in_array($part, $allowed, true) && !in_array($part, $selected, true)) {
            $selected[] = $part;
        }
    }

    return $selected;
}

function contract_duplicate_runtime_keys(): array
{
    return [
        'id',
        'sign_token',
        'sign_url',
        'customer_url',
        'partner_api_raw',
        'partner_api_id',
        'partner_api_signed',
        'status',
        'contract_status',
        'signed_at',
        'pdf_path',
        'signed_pdf_path',
        'pdf_url',
        'pdf_viewed_at',
        'signer_name',
        'signatures_completed',
        'registration_email',
        'registration_emails_sent_at',
        'registration_email_log',
        'link_first_access',
        'link_last_access',
        'link_access_log',
        'customer_location',
        'api_raw_data',
        'raw_data',
    ];
}

function contract_extract_full_snapshot(array $source): array
{
    $layers = [];

    if (!empty($source['api_raw_data']) && is_array($source['api_raw_data'])) {
        $layers[] = $source['api_raw_data'];
    }

    if (!empty($source['raw_data']) && is_array($source['raw_data'])) {
        $layers[] = $source['raw_data'];
    }

    if (!empty($source['partner_api_raw']) && is_array($source['partner_api_raw'])) {
        if (!empty($source['partner_api_raw']['raw_data']) && is_array($source['partner_api_raw']['raw_data'])) {
            $layers[] = $source['partner_api_raw']['raw_data'];
        }
        $layers[] = $source['partner_api_raw'];
    }

    $snapshot = $source;
    foreach ($layers as $layer) {
        $snapshot = array_merge($layer, $snapshot);
    }

    $local = null;
    foreach (contract_all_tokens($snapshot) as $candidate) {
        $local = local_store_find($candidate);
        if ($local !== null) {
            break;
        }
    }

    $contractId = (int)($snapshot['id'] ?? $snapshot['partner_api_id'] ?? 0);
    if ($local === null && $contractId > 0) {
        $local = local_store_find_by_id($contractId);
    }

    if ($local !== null) {
        if (!empty($local['api_raw_data']) && is_array($local['api_raw_data'])) {
            $snapshot = array_merge($local['api_raw_data'], $snapshot);
        }
        $snapshot = array_merge($local, $snapshot);
    }

    return $snapshot;
}

function contract_apply_derived_fields(array $contract): array
{
    $contract['brands'] = contract_brands_from_record($contract);
    $ownerNames = is_array($contract['owner_names'] ?? null) ? $contract['owner_names'] : [];

    if ($ownerNames === [] && !empty($contract['owner_name'])) {
        $ownerNames = array_map('trim', explode(',', (string)$contract['owner_name']));
    }

    $ownerNames = array_values(array_filter($ownerNames, static fn($name): bool => trim((string)$name) !== ''));
    $contract['number_of_owners'] = (string)contract_normalize_owner_count(
        $contract['number_of_owners'] ?? count($ownerNames) ?: 1
    );
    $contract['owner_names'] = array_slice(
        $ownerNames,
        0,
        contract_normalize_owner_count($contract['number_of_owners'])
    );
    $contract['brand'] = contract_brand_display_names($contract['brands']);
    $contract['owner_name'] = contract_owner_name_display($contract['owner_names']);
    $contract['partner_name'] = (string)(($contract['restaurant_name'] ?? '') ?: (($contract['owner_name'] ?? '') ?: ($contract['legal_name'] ?? '')));
    $contract['partner_email'] = (string)($contract['email'] ?? '');
    $contract['partner_phone'] = (string)(($contract['company_phone'] ?? '') ?: ($contract['contact_mobile'] ?? ''));
    $contract['partner_address'] = trim(
        (string)($contract['street'] ?? '') . ', '
        . (string)($contract['postal_city'] ?? '') . ', '
        . (string)($contract['country'] ?? ''),
        ', '
    );
    $contract['business_name'] = (string)((($contract['legal_name'] ?? '') ?: ($contract['restaurant_name'] ?? '')));
    $contract['partnership_type'] = (string)($contract['brand'] ?? '');

    if (trim((string)($contract['contract_date'] ?? '')) === '') {
        $contract['contract_date'] = date('Y-m-d');
    }

    return $contract;
}

function contract_prepare_duplicate(array $source): array
{
    $snapshot = contract_extract_full_snapshot($source);
    $sourceToken = local_store_resolve_token($snapshot);
    $sourceId = (int)($snapshot['id'] ?? $snapshot['partner_api_id'] ?? 0);

    $duplicate = $snapshot;

    foreach (contract_duplicate_runtime_keys() as $key) {
        unset($duplicate[$key]);
    }

    foreach (contract_all_field_names() as $name) {
        if (array_key_exists($name, $snapshot)) {
            $duplicate[$name] = $snapshot[$name];
        }
    }

    $duplicate = contract_apply_derived_fields($duplicate);
    $duplicate['token'] = generate_token();
    $duplicate['status'] = 'pending';
    $duplicate['created_at'] = date('Y-m-d H:i:s');
    $duplicate['signed_at'] = null;
    $duplicate['pdf_path'] = '';
    $duplicate['signed_pdf_path'] = '';
    $duplicate['pdf_viewed_at'] = '';
    $duplicate['signer_name'] = '';
    $duplicate['registration_email'] = '';
    $duplicate['registration_emails_sent_at'] = '';
    $duplicate['partner_api_signed'] = false;
    $duplicate['signatures_completed'] = 0;
    $duplicate['link_first_access'] = null;
    $duplicate['link_last_access'] = null;
    $duplicate['link_access_log'] = [];
    $duplicate['customer_location'] = null;
    $duplicate['duplicated_from_token'] = $sourceToken;
    $duplicate['duplicated_from_id'] = $sourceId > 0 ? $sourceId : null;

    return $duplicate;
}
