<?php

namespace App\Traits;

use App\Models\Tenants\ExpenseAccount;
use App\Models\Tenants\JournalEntry;

/**
 * 전표 저장/수정/삭제 시 expense_accounts 동기화 (복리후생비/접대비 → CEO 대시보드)
 *
 * 사용처: GeneralJournalEntryService, JournalSyncService
 */
trait SyncsExpenseAccounts
{
    /**
     * 계정과목명 → expense_accounts account_type 매핑
     */
    private static array $expenseAccountMap = [
        '복리후생비' => ExpenseAccount::TYPE_WELFARE,
        '접대비' => ExpenseAccount::TYPE_ENTERTAINMENT,
    ];

    /**
     * 전표 저장/수정 후 expense_accounts 동기화
     * 복리후생비/접대비 계정과목이 포함된 lines → expense_accounts에 반영
     */
    protected function syncExpenseAccounts(JournalEntry $entry): void
    {
        $tenantId = $entry->tenant_id;

        // 1. 기존 이 전표에서 생성된 expense_accounts 삭제
        ExpenseAccount::where('tenant_id', $tenantId)
            ->where('journal_entry_id', $entry->id)
            ->forceDelete();

        // 2. 현재 lines 중 복리후생비/접대비 해당하는 것만 insert
        $lines = $entry->lines()->get();

        foreach ($lines as $line) {
            $accountType = $this->getExpenseAccountType($line->account_name);
            if (! $accountType) {
                continue;
            }

            // 차변(debit)이 대변보다 큰 경우만 비용 발생으로 처리
            $amount = $line->debit_amount - $line->credit_amount;
            if ($amount <= 0) {
                continue;
            }

            // source_type에 따라 payment_method 결정
            $paymentMethod = match ($entry->source_type) {
                JournalEntry::SOURCE_CARD_TRANSACTION => ExpenseAccount::PAYMENT_CARD,
                default => ExpenseAccount::PAYMENT_TRANSFER,
            };

            ExpenseAccount::create([
                'tenant_id' => $tenantId,
                'account_type' => $accountType,
                'sub_type' => null,
                'expense_date' => $entry->entry_date,
                'amount' => $amount,
                'description' => $line->description ?? $entry->description,
                'receipt_no' => null,
                'vendor_id' => $line->trading_partner_id,
                'vendor_name' => $line->trading_partner_name,
                'payment_method' => $paymentMethod,
                'card_no' => null,
                'journal_entry_id' => $entry->id,
                'journal_entry_line_id' => $line->id,
            ]);
        }
    }

    /**
     * 전표 삭제 시 expense_accounts 정리
     */
    protected function cleanupExpenseAccounts(int $tenantId, int $entryId): void
    {
        ExpenseAccount::where('tenant_id', $tenantId)
            ->where('journal_entry_id', $entryId)
            ->forceDelete();
    }

    /**
     * 계정과목명에서 비용 유형 판별
     */
    private function getExpenseAccountType(string $accountName): ?string
    {
        foreach (self::$expenseAccountMap as $keyword => $type) {
            if (str_contains($accountName, $keyword)) {
                return $type;
            }
        }

        return null;
    }
}
