<?php

namespace App\Observers\ExpenseSync;

use App\Models\Tenants\ExpectedExpense;
use App\Models\Tenants\Withdrawal;

/**
 * 카드결제 데이터를 예상 지출(expected_expenses)로 자동 동기화
 * (payment_method = 'card' 인 경우만)
 */
class WithdrawalExpenseSyncObserver
{
    /**
     * 출금 생성 시 → 카드결제인 경우 예상 지출 생성
     */
    public function created(Withdrawal $withdrawal): void
    {
        if ($this->isCardPayment($withdrawal)) {
            $this->syncToExpectedExpense($withdrawal);
        }
    }

    /**
     * 출금 수정 시 → 카드결제 상태 변경 처리
     */
    public function updated(Withdrawal $withdrawal): void
    {
        $wasCard = $withdrawal->getOriginal('payment_method') === 'card';
        $isCard = $this->isCardPayment($withdrawal);

        if ($isCard) {
            // 카드결제 → 동기화
            $this->syncToExpectedExpense($withdrawal);
        } elseif ($wasCard && ! $isCard) {
            // 카드결제에서 다른 방법으로 변경 → 예상 지출 삭제
            $this->deleteExpectedExpense($withdrawal);
        }
    }

    /**
     * 출금 삭제 시 → 예상 지출 삭제
     */
    public function deleted(Withdrawal $withdrawal): void
    {
        if ($this->isCardPayment($withdrawal)) {
            $this->deleteExpectedExpense($withdrawal);
        }
    }

    /**
     * 출금 복원 시 → 카드결제인 경우 예상 지출 복원
     */
    public function restored(Withdrawal $withdrawal): void
    {
        if (! $this->isCardPayment($withdrawal)) {
            return;
        }

        $expense = ExpectedExpense::withTrashed()
            ->withoutGlobalScopes()
            ->bySource('withdrawals', $withdrawal->id)
            ->first();

        if ($expense) {
            $expense->restore();
            $this->updateExpectedExpense($expense, $withdrawal);
        } else {
            $this->createExpectedExpense($withdrawal);
        }
    }

    /**
     * 출금 강제 삭제 시 → 예상 지출 강제 삭제
     */
    public function forceDeleted(Withdrawal $withdrawal): void
    {
        ExpectedExpense::withTrashed()
            ->withoutGlobalScopes()
            ->bySource('withdrawals', $withdrawal->id)
            ->forceDelete();
    }

    /**
     * 카드결제 여부 확인
     */
    protected function isCardPayment(Withdrawal $withdrawal): bool
    {
        return $withdrawal->payment_method === 'card';
    }

    /**
     * 예상 지출에 동기화
     */
    protected function syncToExpectedExpense(Withdrawal $withdrawal): void
    {
        $expense = ExpectedExpense::withoutGlobalScopes()
            ->bySource('withdrawals', $withdrawal->id)
            ->first();

        if ($expense) {
            $this->updateExpectedExpense($expense, $withdrawal);
        } else {
            $this->createExpectedExpense($withdrawal);
        }
    }

    /**
     * 예상 지출 삭제
     */
    protected function deleteExpectedExpense(Withdrawal $withdrawal): void
    {
        ExpectedExpense::withoutGlobalScopes()
            ->bySource('withdrawals', $withdrawal->id)
            ->delete();
    }

    /**
     * 예상 지출 생성
     */
    protected function createExpectedExpense(Withdrawal $withdrawal): void
    {
        ExpectedExpense::create([
            'tenant_id' => $withdrawal->tenant_id,
            'expected_payment_date' => $withdrawal->withdrawal_date,
            'transaction_type' => 'card',
            'amount' => $withdrawal->amount,
            'client_id' => $withdrawal->client_id,
            'client_name' => $withdrawal->client_name ?? $withdrawal->merchant_name,
            'bank_account_id' => $withdrawal->bank_account_id,
            'account_code' => $withdrawal->account_code,
            'description' => $withdrawal->description,
            'payment_status' => 'paid', // 카드결제는 이미 결제 완료 상태
            'approval_status' => 'none',
            'source_type' => 'withdrawals',
            'source_id' => $withdrawal->id,
            'created_by' => $withdrawal->created_by,
            'updated_by' => $withdrawal->updated_by,
        ]);
    }

    /**
     * 예상 지출 업데이트
     */
    protected function updateExpectedExpense(ExpectedExpense $expense, Withdrawal $withdrawal): void
    {
        $expense->update([
            'expected_payment_date' => $withdrawal->withdrawal_date,
            'amount' => $withdrawal->amount,
            'client_id' => $withdrawal->client_id,
            'client_name' => $withdrawal->client_name ?? $withdrawal->merchant_name,
            'bank_account_id' => $withdrawal->bank_account_id,
            'account_code' => $withdrawal->account_code,
            'description' => $withdrawal->description,
            'updated_by' => $withdrawal->updated_by,
        ]);
    }
}
