<?php
namespace App\Controllers;

use App\Services\DidarApiService;
use App\Services\SyncService;
use App\Repositories\ConfigRepository;
use App\Repositories\UserRepository;
use App\Utils\Sanitizer;
use App\Utils\Logger;

class SetupController extends ApiController
{
    private $didarApi;
    private $syncService;
    private $configRepo;
    private $userRepo;
    private $db;

    public function __construct($didarApi, $syncService, $configRepo, $userRepo, $db)
    {
        $this->didarApi = $didarApi;
        $this->syncService = $syncService;
        $this->configRepo = $configRepo;
        $this->userRepo = $userRepo;
        $this->db = $db;
    }

    public function init()
    {
        $pdo = $this->db->getPdo();
        
        // Check if system already initialized
        if ($this->userRepo->countByRole('admin') > 0) {
            $this->errorResponse('سیستم قبلاً نصب شده است.');
        }

        $apiKey = trim(Sanitizer::sanitize($_POST['api_key'] ?? ''));
        if (empty($apiKey)) {
            $this->errorResponse('API Key الزامی است');
        }

        Logger::logInfo("Testing API key", ['api_key_preview' => substr($apiKey, 0, 10) . '...']);

        // Test API with provided key
        $usersRes = $this->didarApi->call('/User/List', 'POST', [], $apiKey);
        
        if (isset($usersRes['error'])) {
            $errorMsg = $usersRes['error'];
            $httpCode = $usersRes['http_code'] ?? null;
            
            if ($httpCode == 401) {
                $this->errorResponse('API Key نامعتبر است. لطفاً API Key صحیح را وارد کنید.');
            } elseif ($httpCode == 0 || isset($usersRes['curl_errno'])) {
                $curlErrno = $usersRes['curl_errno'] ?? 0;
                if ($curlErrno == CURLE_COULDNT_CONNECT || $curlErrno == CURLE_OPERATION_TIMEOUTED) {
                    $this->errorResponse('خطا در اتصال به سرور دیدار. لطفاً اتصال اینترنت خود را بررسی کنید و دوباره تلاش کنید.');
                } else {
                    $this->errorResponse('خطا در ارتباط با سرور دیدار: ' . $errorMsg);
                }
            } else {
                $this->errorResponse('خطا در ارتباط با API دیدار: ' . $errorMsg);
            }
        }
        
        if (!isset($usersRes['Response']) || !is_array($usersRes['Response'])) {
            $this->errorResponse('پاسخ نامعتبر از API دیدار. لطفاً API Key را بررسی کنید.');
        }
        
        if (empty($usersRes['Response'])) {
            $this->errorResponse('هیچ کاربری در حساب دیدار یافت نشد. لطفاً API Key را بررسی کنید.');
        }
        
        // Save API Key
        $this->configRepo->setValue('api_key', $apiKey);
        
        Logger::logInfo("Setup init completed successfully", ['users_count' => count($usersRes['Response'])]);
        
        $this->successResponse(['users' => $usersRes['Response'] ?? []]);
    }

    public function complete()
    {
        $apiKey = Sanitizer::sanitize($_POST['api_key'] ?? '');
        $adminDidarId = Sanitizer::sanitize($_POST['admin_didar_id'] ?? '');
        
        if (empty($adminDidarId)) {
            $this->errorResponse('لطفاً کاربر ادمین را انتخاب کنید');
        }
        
        // Find admin user from Didar users
        $usersRes = $this->didarApi->call('/User/List', 'POST');
        $adminUser = null;
        foreach ($usersRes['Response'] ?? [] as $user) {
            if ($user['Id'] === $adminDidarId || $user['UserId'] === $adminDidarId) {
                $adminUser = $user;
                break;
            }
        }
        
        if (!$adminUser) {
            $this->errorResponse('کاربر انتخابی یافت نشد');
        }
        
        // Insert or update admin user
        $user = new \App\Models\User([
            'didar_user_id' => $adminUser['UserId'] ?? $adminUser['Id'] ?? '',
            'email' => $adminUser['UserName'] ?? '',
            'first_name' => $adminUser['FirstName'] ?? '',
            'last_name' => $adminUser['LastName'] ?? '',
            'display_name' => $adminUser['DisplayName'] ?? '',
            'role' => 'admin',
            'is_active' => 1
        ]);
        
        $this->userRepo->save($user);
        
        if (!$this->configRepo->getValue('crm_owner_id')) {
            $this->configRepo->setValue('crm_owner_id', $adminUser['UserId'] ?? $adminUser['Id'] ?? '');
            $this->configRepo->setValue('crm_owner_name', $adminUser['DisplayName'] ?? '');
        }
        
        $this->successResponse([], 'Setup تکمیل شد. در حال بارگذاری داده‌ها...');
    }

    public function sync()
    {
        $step = $_POST['step'] ?? 'users';
        $from = intval($_POST['from'] ?? 0);
        $limit = ($step === 'deals') ? 250 : 500;
        
        try {
            $result = null;
            switch($step) {
                case 'users':
                    $result = $this->syncService->syncUsers($from, $limit);
                    break;
                case 'persons':
                    $result = $this->syncService->syncPersons($from, $limit);
                    break;
                case 'deals':
                    $result = $this->syncService->syncDeals($from, $limit);
                    break;
                case 'activities':
                    $result = $this->syncService->syncActivities($from, $limit);
                    break;
            }
            
            $progress = $this->calculateProgress($step);
            $nextStep = $this->getNextStep($step, $result);
            
            $this->successResponse([
                'progress' => $progress,
                'next_step' => $nextStep,
                'from' => $from,
                'total_count' => $result['total'] ?? 0,
                'limit' => $limit,
                'synced' => $result['synced'] ?? 0
            ], "مرحله $step تکمیل شد");
        } catch (Exception $e) {
            $this->errorResponse($e->getMessage());
        }
    }

    /**
     * Get current sync status (for resume functionality)
     * Public endpoint, used by setup UI.
     */
    public function getSyncStatus()
    {
        try {
            $pdo = $this->db->getPdo();

            // Count synced entities
            $personsCount = (int)$pdo->query("SELECT COUNT(*) FROM persons")->fetchColumn();
            $dealsCount   = (int)$pdo->query("SELECT COUNT(*) FROM deals")->fetchColumn();
            $usersCount   = (int)$pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();

            // Last sync timestamps if available
            $lastPersonSync = $pdo->query("SELECT MAX(last_sync) FROM persons")->fetchColumn();
            $lastDealSync   = $pdo->query("SELECT MAX(last_sync) FROM deals")->fetchColumn();

            // Expected deals count (from original system analysis)
            $expectedDeals  = 18327;
            $dealsProgress  = $expectedDeals > 0
                ? round(($dealsCount / $expectedDeals) * 100, 2)
                : 0;

            $this->successResponse([
                'counts' => [
                    'users'          => $usersCount,
                    'persons'        => $personsCount,
                    'deals'          => $dealsCount,
                    'expected_deals' => $expectedDeals,
                ],
                'progress' => [
                    'deals' => $dealsProgress,
                ],
                'last_sync' => [
                    'persons' => $lastPersonSync,
                    'deals'   => $lastDealSync,
                ],
            ]);
        } catch (Exception $e) {
            $this->errorResponse($e->getMessage());
        }
    }

    /**
     * Resume sync from last saved position.
     * Public endpoint, used by setup UI when sync is interrupted.
     */
    public function resumeSync()
    {
        try {
            $pdo = $this->db->getPdo();

            // Ensure system has been initialized (admin exists)
            if ($this->userRepo->countByRole('admin') === 0) {
                $this->errorResponse('نصب اولیه انجام نشده است. لطفاً ابتدا نصب را انجام دهید.');
            }

            $step = 'users';
            $from = 0;

            // Try to get progress from config table (most accurate)
            $progressJson = $this->configRepo->getValue('setup_progress');
            if ($progressJson) {
                $progressData = json_decode($progressJson, true);
                if (is_array($progressData) && isset($progressData['step'])) {
                    $step = $progressData['step'];
                    $from = $progressData['from'] ?? 0;

                    // If step is 'deals' and we have current_from, use it for more accuracy
                    if ($step === 'deals' && isset($progressData['current_from'])) {
                        $from = $progressData['current_from'] + ($progressData['current_limit'] ?? 250);
                    }
                }
            } else {
                // Fallback: determine step from current DB counts (simplified vs legacy)
                $usersCount   = (int)$pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
                $personsCount = (int)$pdo->query("SELECT COUNT(*) FROM persons")->fetchColumn();
                $dealsCount   = (int)$pdo->query("SELECT COUNT(*) FROM deals")->fetchColumn();

                if ($usersCount === 0) {
                    $step = 'users';
                    $from = 0;
                } elseif ($personsCount === 0) {
                    $step = 'persons';
                    $from = 0;
                } elseif ($dealsCount === 0) {
                    $step = 'deals';
                    $from = 0;
                } else {
                    // All main entities have data; continue with activities or mark as complete
                    $step = 'activities';
                    $from = 0;
                }
            }

            $this->successResponse([
                'step' => $step,
                'from' => $from,
            ], "ادامه همگام‌سازی از مرحله {$step}");
        } catch (Exception $e) {
            $this->errorResponse($e->getMessage());
        }
    }

    private function calculateProgress($step)
    {
        $progressMap = [
            'users' => 25,
            'persons' => 50,
            'deals' => 75,
            'activities' => 100
        ];
        return $progressMap[$step] ?? 0;
    }

    private function getNextStep($currentStep, $result)
    {
        if (isset($result['has_more']) && $result['has_more']) {
            return $currentStep; // Continue same step
        }
        
        $steps = ['users' => 'persons', 'persons' => 'deals', 'deals' => 'activities', 'activities' => 'complete'];
        return $steps[$currentStep] ?? 'complete';
    }
}

