<?php

namespace App\Models\Finance;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;

class JournalEntry extends Model
{
    use SoftDeletes;

    protected $table = 'journal_entries';

    protected $fillable = [
        'tenant_id',
        'entry_no',
        'entry_date',
        'entry_type',
        'description',
        'total_debit',
        'total_credit',
        'status',
        'source_type',
        'source_key',
        'created_by_name',
        'attachment_note',
    ];

    protected $casts = [
        'entry_date' => 'date',
        'total_debit' => 'integer',
        'total_credit' => 'integer',
    ];

    public function lines()
    {
        return $this->hasMany(JournalEntryLine::class)->orderBy('line_no');
    }

    public function scopeForTenant($query, $tenantId)
    {
        return $query->where('tenant_id', $tenantId);
    }

    /**
     * 분개 완료된 source_key 일괄 조회
     * 레거시(summary 미포함) 형식과 신규(summary 포함) 형식 모두 매칭
     */
    public static function getJournaledSourceKeys(int $tenantId, string $sourceType, array $sourceKeys): array
    {
        if (empty($sourceKeys)) {
            return [];
        }

        // 레거시 키도 함께 검색 (새 키에서 마지막 |summary 부분 제거)
        $allKeys = $sourceKeys;
        $legacyToNewMap = [];
        foreach ($sourceKeys as $key) {
            $parts = explode('|', $key);
            if (count($parts) === 6) {
                $legacyKey = implode('|', array_slice($parts, 0, 5));
                $allKeys[] = $legacyKey;
                $legacyToNewMap[$legacyKey] = $key;
            }
        }

        $found = static::where('tenant_id', $tenantId)
            ->where('source_type', $sourceType)
            ->whereIn('source_key', array_unique($allKeys))
            ->pluck('source_key')
            ->toArray();

        // 레거시 키로 매칭된 것을 새 키 형식으로 변환하여 반환
        $result = [];
        foreach ($found as $key) {
            if (in_array($key, $sourceKeys)) {
                $result[] = $key;
            } elseif (isset($legacyToNewMap[$key])) {
                $result[] = $legacyToNewMap[$key];
            }
        }

        return array_unique($result);
    }

    /**
     * source_key로 분개 전표 조회 (ID 포함)
     * 레거시(summary 미포함) 형식과 신규(summary 포함) 형식 모두 매칭
     */
    public static function getJournalBySourceKey(int $tenantId, string $sourceType, string $sourceKey)
    {
        $keys = [$sourceKey];
        $parts = explode('|', $sourceKey);
        if (count($parts) === 6) {
            $keys[] = implode('|', array_slice($parts, 0, 5));
        }

        return static::where('tenant_id', $tenantId)
            ->where('source_type', $sourceType)
            ->whereIn('source_key', $keys)
            ->first();
    }

    /**
     * 전표번호 자동채번: JE-YYYYMMDD-NNN
     */
    public static function generateEntryNo($tenantId, $date)
    {
        $dateStr = date('Ymd', strtotime($date));
        $prefix = "JE-{$dateStr}-";

        // withTrashed: soft-deleted 레코드도 포함하여 채번 (DB unique 제약 충돌 방지)
        $last = static::withTrashed()
            ->where('tenant_id', $tenantId)
            ->where('entry_no', 'like', $prefix.'%')
            ->lockForUpdate()
            ->orderByDesc('entry_no')
            ->value('entry_no');

        if ($last) {
            $seq = (int) substr($last, -3) + 1;
        } else {
            $seq = 1;
        }

        return $prefix.str_pad($seq, 3, '0', STR_PAD_LEFT);
    }
}
