<?php

namespace App\Models\Sales;

use App\Models\Tenants\Tenant;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 영업 시나리오 체크리스트 모델
 *
 * @property int $id
 * @property int $tenant_id
 * @property string $scenario_type (sales/manager)
 * @property int $step_id
 * @property string|null $checkpoint_id
 * @property int|null $checkpoint_index
 * @property bool $is_checked
 * @property \Carbon\Carbon|null $checked_at
 * @property int|null $checked_by
 * @property string|null $memo
 */
class SalesScenarioChecklist extends Model
{
    protected $table = 'sales_scenario_checklists';

    protected $fillable = [
        'tenant_id',
        'tenant_prospect_id',
        'scenario_type',
        'step_id',
        'checkpoint_id',
        'checkpoint_index',
        'is_checked',
        'checked_at',
        'checked_by',
        'memo',
        'user_id', // 하위 호환성
    ];

    protected $casts = [
        'step_id' => 'integer',
        'checkpoint_index' => 'integer',
        'is_checked' => 'boolean',
        'checked_at' => 'datetime',
    ];

    /**
     * 테넌트 관계
     */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

    /**
     * 가망고객 관계
     */
    public function tenantProspect(): BelongsTo
    {
        return $this->belongsTo(TenantProspect::class, 'tenant_prospect_id');
    }

    /**
     * 체크한 사용자 관계
     */
    public function checkedByUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'checked_by');
    }

    /**
     * 사용자 관계 (하위 호환성)
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * 체크포인트 토글 (tenant_id 기반)
     */
    public static function toggle(int $tenantId, string $scenarioType, int $stepId, string $checkpointId, bool $checked, ?int $userId = null): self
    {
        $currentUserId = $userId ?? auth()->id();

        $checklist = self::firstOrNew([
            'tenant_id' => $tenantId,
            'scenario_type' => $scenarioType,
            'step_id' => $stepId,
            'checkpoint_id' => $checkpointId,
        ]);

        // 새 레코드인 경우 필수 필드 설정
        if (! $checklist->exists) {
            $checklist->user_id = $currentUserId;
            $checklist->checkpoint_index = 0; // 기본값
        }

        $checklist->is_checked = $checked;
        $checklist->checked_at = $checked ? now() : null;
        $checklist->checked_by = $checked ? $currentUserId : null;
        $checklist->save();

        return $checklist;
    }

    /**
     * 체크포인트 토글 (prospect_id 기반)
     */
    public static function toggleByProspect(int $prospectId, string $scenarioType, int $stepId, string $checkpointId, bool $checked, ?int $userId = null): self
    {
        $currentUserId = $userId ?? auth()->id();

        $checklist = self::firstOrNew([
            'tenant_prospect_id' => $prospectId,
            'scenario_type' => $scenarioType,
            'step_id' => $stepId,
            'checkpoint_id' => $checkpointId,
        ]);

        // 새 레코드인 경우 필수 필드 설정
        if (! $checklist->exists) {
            $checklist->user_id = $currentUserId;
            $checklist->checkpoint_index = 0;
        }

        $checklist->is_checked = $checked;
        $checklist->checked_at = $checked ? now() : null;
        $checklist->checked_by = $checked ? $currentUserId : null;
        $checklist->save();

        // 체크 완료 시 진행률 100% 확인 후 상태 자동 전환
        if ($checked) {
            self::checkAndConvertProspectStatus($prospectId, $currentUserId);
        }

        return $checklist;
    }

    /**
     * 진행률 100% 시 가망고객 상태를 '계약완료'로 자동 전환
     */
    public static function checkAndConvertProspectStatus(int $prospectId, ?int $userId = null): bool
    {
        $progress = self::getProspectProgress($prospectId);

        // 영업 시나리오와 매니저 시나리오 모두 100%인 경우에만 전환
        if ($progress['sales']['percentage'] === 100 && $progress['manager']['percentage'] === 100) {
            $prospect = TenantProspect::find($prospectId);

            if ($prospect && $prospect->status !== TenantProspect::STATUS_CONVERTED) {
                $prospect->update([
                    'status' => TenantProspect::STATUS_CONVERTED,
                    'converted_at' => now(),
                    'converted_by' => $userId ?? auth()->id(),
                ]);

                return true;
            }
        }

        return false;
    }

    /**
     * 특정 테넌트/시나리오의 체크리스트 조회
     */
    public static function getChecklist(int $tenantId, string $scenarioType): array
    {
        $items = self::where('tenant_id', $tenantId)
            ->where('scenario_type', $scenarioType)
            ->where('is_checked', true)
            ->get();

        $result = [];
        foreach ($items as $item) {
            $key = "{$item->step_id}_{$item->checkpoint_id}";
            $result[$key] = [
                'checked_at' => $item->checked_at?->toDateTimeString(),
                'checked_by' => $item->checked_by,
            ];
        }

        return $result;
    }

    /**
     * 특정 가망고객/시나리오의 체크리스트 조회
     */
    public static function getChecklistByProspect(int $prospectId, string $scenarioType): array
    {
        $items = self::where('tenant_prospect_id', $prospectId)
            ->where('scenario_type', $scenarioType)
            ->where('is_checked', true)
            ->get();

        $result = [];
        foreach ($items as $item) {
            $key = "{$item->step_id}_{$item->checkpoint_id}";
            $result[$key] = [
                'checked_at' => $item->checked_at?->toDateTimeString(),
                'checked_by' => $item->checked_by,
            ];
        }

        return $result;
    }

    /**
     * 진행률 계산
     */
    public static function calculateProgress(int $tenantId, string $scenarioType, array $steps): array
    {
        $checklist = self::getChecklist($tenantId, $scenarioType);

        $totalCheckpoints = 0;
        $completedCheckpoints = 0;
        $stepProgress = [];

        foreach ($steps as $step) {
            $stepCompleted = 0;
            $stepTotal = count($step['checkpoints'] ?? []);
            $totalCheckpoints += $stepTotal;

            foreach ($step['checkpoints'] as $checkpoint) {
                $key = "{$step['id']}_{$checkpoint['id']}";
                if (isset($checklist[$key])) {
                    $completedCheckpoints++;
                    $stepCompleted++;
                }
            }

            $stepProgress[$step['id']] = [
                'total' => $stepTotal,
                'completed' => $stepCompleted,
                'percentage' => $stepTotal > 0 ? round(($stepCompleted / $stepTotal) * 100) : 0,
            ];
        }

        return [
            'total' => $totalCheckpoints,
            'completed' => $completedCheckpoints,
            'percentage' => $totalCheckpoints > 0 ? round(($completedCheckpoints / $totalCheckpoints) * 100) : 0,
            'steps' => $stepProgress,
        ];
    }

    /**
     * 가망고객 기반 진행률 계산
     */
    public static function calculateProgressByProspect(int $prospectId, string $scenarioType, array $steps): array
    {
        $checklist = self::getChecklistByProspect($prospectId, $scenarioType);

        $totalCheckpoints = 0;
        $completedCheckpoints = 0;
        $stepProgress = [];

        foreach ($steps as $step) {
            $stepCompleted = 0;
            $stepTotal = count($step['checkpoints'] ?? []);
            $totalCheckpoints += $stepTotal;

            foreach ($step['checkpoints'] as $checkpoint) {
                $key = "{$step['id']}_{$checkpoint['id']}";
                if (isset($checklist[$key])) {
                    $completedCheckpoints++;
                    $stepCompleted++;
                }
            }

            $stepProgress[$step['id']] = [
                'total' => $stepTotal,
                'completed' => $stepCompleted,
                'percentage' => $stepTotal > 0 ? round(($stepCompleted / $stepTotal) * 100) : 0,
            ];
        }

        return [
            'total' => $totalCheckpoints,
            'completed' => $completedCheckpoints,
            'percentage' => $totalCheckpoints > 0 ? round(($completedCheckpoints / $totalCheckpoints) * 100) : 0,
            'steps' => $stepProgress,
        ];
    }

    /**
     * 시나리오 타입 스코프
     */
    public function scopeByScenarioType($query, string $type)
    {
        return $query->where('scenario_type', $type);
    }

    /**
     * 체크된 항목만 스코프
     */
    public function scopeChecked($query)
    {
        return $query->where('is_checked', true);
    }

    /**
     * 간단한 진행률 계산 (전체 체크포인트 수 기준)
     *
     * @param  string  $scenarioType  'sales' 또는 'manager'
     * @return array ['completed' => 완료 수, 'total' => 전체 수, 'percentage' => 백분율]
     */
    public static function getSimpleProgress(int $tenantId, string $scenarioType): array
    {
        // 전체 체크포인트 수 (config에서 계산)
        $configKey = $scenarioType === 'sales' ? 'sales_scenario.sales_steps' : 'sales_scenario.manager_steps';
        $steps = config($configKey, []);

        $total = 0;
        $validCheckpointKeys = [];

        // config에 정의된 유효한 체크포인트만 수집
        foreach ($steps as $step) {
            foreach ($step['checkpoints'] ?? [] as $checkpoint) {
                $total++;
                $validCheckpointKeys[] = "{$step['id']}_{$checkpoint['id']}";
            }
        }

        // 완료된 체크포인트 수 (config에 존재하는 것만 카운트)
        $checkedItems = self::where('tenant_id', $tenantId)
            ->where('scenario_type', $scenarioType)
            ->where('is_checked', true)
            ->get();

        $completed = 0;
        foreach ($checkedItems as $item) {
            $key = "{$item->step_id}_{$item->checkpoint_id}";
            if (in_array($key, $validCheckpointKeys)) {
                $completed++;
            }
        }

        $percentage = $total > 0 ? round(($completed / $total) * 100) : 0;

        return [
            'completed' => $completed,
            'total' => $total,
            'percentage' => $percentage,
        ];
    }

    /**
     * 테넌트별 영업/매니저 진행률 한번에 조회
     */
    public static function getTenantProgress(int $tenantId): array
    {
        return [
            'sales' => self::getSimpleProgress($tenantId, 'sales'),
            'manager' => self::getSimpleProgress($tenantId, 'manager'),
        ];
    }

    /**
     * 가망고객별 간단한 진행률 계산
     */
    public static function getSimpleProgressByProspect(int $prospectId, string $scenarioType): array
    {
        $configKey = $scenarioType === 'sales' ? 'sales_scenario.sales_steps' : 'sales_scenario.manager_steps';
        $steps = config($configKey, []);

        $total = 0;
        $validCheckpointKeys = [];

        foreach ($steps as $step) {
            foreach ($step['checkpoints'] ?? [] as $checkpoint) {
                $total++;
                $validCheckpointKeys[] = "{$step['id']}_{$checkpoint['id']}";
            }
        }

        $checkedItems = self::where('tenant_prospect_id', $prospectId)
            ->where('scenario_type', $scenarioType)
            ->where('is_checked', true)
            ->get();

        $completed = 0;
        foreach ($checkedItems as $item) {
            $key = "{$item->step_id}_{$item->checkpoint_id}";
            if (in_array($key, $validCheckpointKeys)) {
                $completed++;
            }
        }

        $percentage = $total > 0 ? round(($completed / $total) * 100) : 0;

        return [
            'completed' => $completed,
            'total' => $total,
            'percentage' => $percentage,
        ];
    }

    /**
     * 가망고객별 영업/매니저 진행률 한번에 조회
     */
    public static function getProspectProgress(int $prospectId): array
    {
        return [
            'sales' => self::getSimpleProgressByProspect($prospectId, 'sales'),
            'manager' => self::getSimpleProgressByProspect($prospectId, 'manager'),
        ];
    }
}
