<?php
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/nextcloud.php';

function cfh_normalize_local_path($path) {
    $path = urldecode((string)$path);
    $path = trim($path, " \t\n\r\0\x0B\"'");
    return $path;
}

function cfh_sanitize_unit_folder($unitName) {
    $unitName = trim((string)$unitName);
    if ($unitName === '') {
        return 'Geral';
    }
    return preg_replace('/[\/:*?"<>|]/', '_', $unitName);
}

function cfh_get_configured_contracts_root() {
    $configured = '';
    try {
        $pdo = get_db_connection();
        $stmt = $pdo->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'nc_path' LIMIT 1");
        $stmt->execute();
        $configured = (string)($stmt->fetchColumn() ?: '');
    } catch (Throwable $e) {
        $configured = '';
    }

    if ($configured === '') {
        $configured = (string)NC_CONTRACTS_PATH_DEFAULT;
    }

    return cfh_extract_contracts_root($configured);
}

function cfh_extract_contracts_root($path) {
    $path = cfh_normalize_local_path($path);
    if ($path === '') {
        return '';
    }

    $segments = preg_split('#[\\\\/]+#', $path);
    if (!is_array($segments) || empty($segments)) {
        return $path;
    }

    $rebuilt = [];
    foreach ($segments as $index => $segment) {
        if ($segment === '' && $index !== 0) {
            continue;
        }
        $rebuilt[] = $segment;
        if (strcasecmp($segment, 'CONTRATOS') === 0) {
            break;
        }
    }

    $joined = implode(DIRECTORY_SEPARATOR, $rebuilt);
    if (preg_match('/^[A-Za-z]:$/', $joined)) {
        $joined .= DIRECTORY_SEPARATOR;
    }

    return rtrim($joined, "\\/");
}

function cfh_get_remote_contracts_root() {
    $configured = '';
    try {
        $pdo = get_db_connection();
        $stmt = $pdo->prepare("SELECT setting_value FROM system_settings WHERE setting_key = 'nc_path' LIMIT 1");
        $stmt->execute();
        $configured = (string)($stmt->fetchColumn() ?: '');
    } catch (Throwable $e) {
        $configured = '';
    }

    if ($configured === '') {
        $configured = (string)NC_CONTRACTS_PATH_DEFAULT;
    }

    $normalized = trim(str_replace('\\', '/', (string)$configured));
    if ($normalized !== '' && strpos($normalized, '/') === 0 && !preg_match('/^[A-Za-z]:\//', $normalized)) {
        $normalized = ltrim($normalized, '/');
    }
    $normalized = trim($normalized, '/');

    if ($normalized === '' || preg_match('/^[A-Za-z]:\//', $normalized) || strpos($normalized, '//') === 0) {
        return defined('NC_REMOTE_ROOT_DEFAULT') ? (string)NC_REMOTE_ROOT_DEFAULT : 'CONTRATOS';
    }

    return $normalized;
}

function cfh_resolve_local_contracts_root($fullPath = '') {
    $candidate = cfh_get_configured_contracts_root();
    if ($candidate !== '' && stripos($candidate, 'CONTRATOS') !== false) {
        return $candidate;
    }

    $fullPath = cfh_normalize_local_path($fullPath);
    if ($fullPath !== '') {
        $fromFullPath = cfh_extract_contracts_root($fullPath);
        if ($fromFullPath !== '' && stripos($fromFullPath, 'CONTRATOS') !== false) {
            return $fromFullPath;
        }
    }

    return $candidate;
}

function cfh_move_local_file_to_unit($fullPath, $unitFolder, $targetFileName = null) {
    $fullPath = cfh_normalize_local_path($fullPath);
    if ($fullPath === '' || !file_exists($fullPath)) {
        throw new Exception('Arquivo local nao encontrado para movimentacao.');
    }

    $contractsRoot = cfh_resolve_local_contracts_root($fullPath);
    if ($contractsRoot === '') {
        throw new Exception('Nao foi possivel identificar a pasta local CONTRATOS.');
    }

    $targetFileName = $targetFileName ?: basename($fullPath);
    $destDir = rtrim($contractsRoot, "\\/") . DIRECTORY_SEPARATOR . $unitFolder;
    if (!is_dir($destDir) && !@mkdir($destDir, 0777, true) && !is_dir($destDir)) {
        throw new Exception('Nao foi possivel criar a pasta da unidade no diretorio local sincronizado.');
    }

    $destPath = $destDir . DIRECTORY_SEPARATOR . $targetFileName;
    $samePath = strcasecmp(str_replace('/', '\\', $fullPath), str_replace('/', '\\', $destPath)) === 0;
    if ($samePath) {
        return $destPath;
    }

    if (!@rename($fullPath, $destPath)) {
        if (!@copy($fullPath, $destPath) || !@unlink($fullPath)) {
            throw new Exception('Nao foi possivel mover o arquivo local para a pasta da unidade.');
        }
    }

    return $destPath;
}

function cfh_build_remote_contract_path($unitFolder, $fileName) {
    $unitFolder = trim(str_replace('\\', '/', (string)$unitFolder), '/');
    $fileName = basename((string)$fileName);

    if ($unitFolder === '') {
        $unitFolder = 'Geral';
    }

    $remoteRoot = cfh_get_remote_contracts_root();
    return trim($remoteRoot, '/') . '/' . $unitFolder . '/' . $fileName;
}

function cfh_get_backup_dir() {
    $dir = dirname(__DIR__) . '/uploads/contracts_cache';
    if (!is_dir($dir)) {
        @mkdir($dir, 0777, true);
    }
    return $dir;
}

function cfh_get_backup_relative_path($remotePath, $fileName = '') {
    $remotePath = trim(str_replace('\\', '/', (string)$remotePath), '/');
    $safeFileName = preg_replace('/[^A-Za-z0-9._-]/', '_', $fileName ?: basename($remotePath));
    if ($safeFileName === '') {
        $safeFileName = 'contrato.pdf';
    }
    return 'uploads/contracts_cache/' . md5($remotePath) . '_' . $safeFileName;
}

function cfh_get_backup_absolute_path($remotePath, $fileName = '') {
    return dirname(__DIR__) . '/' . cfh_get_backup_relative_path($remotePath, $fileName);
}

function cfh_backup_from_local($localPath, $remotePath, $fileName = '') {
    $localPath = cfh_normalize_local_path($localPath);
    if ($localPath === '' || !file_exists($localPath)) {
        return '';
    }

    $absPath = cfh_get_backup_absolute_path($remotePath, $fileName ?: basename($localPath));
    $dir = dirname($absPath);
    if (!is_dir($dir)) {
        @mkdir($dir, 0777, true);
    }

    return @copy($localPath, $absPath) ? str_replace('\\', '/', cfh_get_backup_relative_path($remotePath, $fileName ?: basename($localPath))) : '';
}

function cfh_backup_from_remote(Nextcloud $nc, $remotePath, $fileName = '') {
    $absPath = cfh_get_backup_absolute_path($remotePath, $fileName ?: basename($remotePath));
    $dir = dirname($absPath);
    if (!is_dir($dir)) {
        @mkdir($dir, 0777, true);
    }

    if ($nc->downloadFile($remotePath, $absPath)) {
        return str_replace('\\', '/', cfh_get_backup_relative_path($remotePath, $fileName ?: basename($remotePath)));
    }

    if (file_exists($absPath)) {
        @unlink($absPath);
    }
    return '';
}

function cfh_remove_backup($remotePath, $fileName = '') {
    $absPath = cfh_get_backup_absolute_path($remotePath, $fileName);
    if (file_exists($absPath)) {
        @unlink($absPath);
    }
}

function cfh_organize_contract_file(Nextcloud $nc, $source, $filePath, $fullPath, $unitName, $targetFileName = null) {
    $source = strtolower(trim((string)$source));
    if ($source === '') {
        $source = 'local';
    }

    $currentRemotePath = trim(str_replace('\\', '/', urldecode((string)$filePath)), '/');
    $currentLocalPath = cfh_normalize_local_path($fullPath);

    $fileName = $targetFileName ?: basename($currentRemotePath ?: $currentLocalPath);
    $fileName = basename((string)$fileName);
    if ($fileName === '') {
        throw new Exception('Nao foi possivel identificar o nome do arquivo.');
    }

    $unitFolder = cfh_sanitize_unit_folder($unitName);
    $destRemotePath = cfh_build_remote_contract_path($unitFolder, $fileName);

    $remoteRoot = cfh_get_remote_contracts_root();
    $remoteRoot = trim(str_replace('\\', '/', (string)$remoteRoot), '/');
    $parts = array_values(array_filter(explode('/', $remoteRoot), 'strlen'));
    $acc = '';
    foreach ($parts as $p) {
        $acc = $acc === '' ? $p : ($acc . '/' . $p);
        $nc->createFolder($acc);
    }
    $nc->createFolder($remoteRoot . '/' . $unitFolder);

    $result = [
        'source' => $source,
        'file_name' => $fileName,
        'unit_folder' => $unitFolder,
        'remote_path' => $currentRemotePath !== '' ? $currentRemotePath : $destRemotePath,
        'full_path' => $currentLocalPath,
        'backup_path' => '',
    ];

    if ($source === 'remote') {
        $finalRemotePath = $currentRemotePath !== '' ? $currentRemotePath : $destRemotePath;
        if ($finalRemotePath !== $destRemotePath) {
            if ($nc->moveFile($finalRemotePath, $destRemotePath)) {
                $finalRemotePath = $destRemotePath;
            }
        }

        $result['remote_path'] = $finalRemotePath;
        $result['backup_path'] = cfh_backup_from_remote($nc, $finalRemotePath, $fileName);
        return $result;
    }

    if ($currentLocalPath === '' || !file_exists($currentLocalPath)) {
        throw new Exception('Arquivo local nao encontrado para movimentacao.');
    }

    $finalLocalPath = cfh_move_local_file_to_unit($currentLocalPath, $unitFolder, $fileName);
    $result['full_path'] = $finalLocalPath;
    $result['remote_path'] = $destRemotePath;

    $uploadSucceeded = false;
    try {
        $uploadSucceeded = $nc->uploadFile($finalLocalPath, $destRemotePath);
    } catch (Throwable $e) {
        $uploadSucceeded = false;
    }

    $backupPath = cfh_backup_from_local($finalLocalPath, $destRemotePath, $fileName);
    if ($backupPath === '' && $uploadSucceeded) {
        $backupPath = cfh_backup_from_remote($nc, $destRemotePath, $fileName);
    }

    $result['backup_path'] = $backupPath;
    return $result;
}
