<?php

namespace App\Services;

use App\Models\Tenants\BankAccount;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

class BankAccountService extends Service
{
    /**
     * 계좌 목록 조회
     */
    public function index(array $params): LengthAwarePaginator
    {
        $tenantId = $this->tenantId();

        $query = BankAccount::query()
            ->where('tenant_id', $tenantId);

        // 검색 필터
        if (! empty($params['search'])) {
            $search = $params['search'];
            $query->where(function ($q) use ($search) {
                $q->where('account_name', 'like', "%{$search}%")
                    ->orWhere('bank_name', 'like', "%{$search}%")
                    ->orWhere('account_holder', 'like', "%{$search}%")
                    ->orWhere('account_number', 'like', "%{$search}%");
            });
        }

        // 상태 필터
        if (! empty($params['status'])) {
            $query->where('status', $params['status']);
        }

        // 담당자 필터
        if (! empty($params['assigned_user_id'])) {
            $query->where('assigned_user_id', $params['assigned_user_id']);
        }

        // 대표계좌만 필터
        if (isset($params['is_primary']) && $params['is_primary']) {
            $query->where('is_primary', true);
        }

        // 정렬: 대표계좌 먼저, 그 다음 생성일순
        $query->orderByDesc('is_primary')
            ->orderBy($params['sort_by'] ?? 'created_at', $params['sort_dir'] ?? 'desc');

        // 페이지네이션
        $perPage = $params['per_page'] ?? 20;

        return $query->paginate($perPage);
    }

    /**
     * 계좌 상세 조회
     */
    public function show(int $id): BankAccount
    {
        $tenantId = $this->tenantId();

        return BankAccount::query()
            ->where('tenant_id', $tenantId)
            ->with(['assignedUser:id,name'])
            ->findOrFail($id);
    }

    /**
     * 계좌 등록
     */
    public function store(array $data): BankAccount
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($data, $tenantId, $userId) {
            // 첫 번째 계좌인 경우 자동으로 대표계좌 설정
            $isFirst = BankAccount::where('tenant_id', $tenantId)->count() === 0;
            $isPrimary = $data['is_primary'] ?? $isFirst;

            // 대표계좌로 설정 시 기존 대표계좌 해제
            if ($isPrimary) {
                BankAccount::where('tenant_id', $tenantId)
                    ->where('is_primary', true)
                    ->update(['is_primary' => false]);
            }

            $account = BankAccount::create([
                'tenant_id' => $tenantId,
                'bank_code' => $data['bank_code'],
                'bank_name' => $data['bank_name'],
                'account_number' => $data['account_number'],
                'account_holder' => $data['account_holder'],
                'account_name' => $data['account_name'],
                'status' => $data['status'] ?? 'active',
                'assigned_user_id' => $data['assigned_user_id'] ?? null,
                'is_primary' => $isPrimary,
                'created_by' => $userId,
                'updated_by' => $userId,
            ]);

            return $account;
        });
    }

    /**
     * 계좌 수정
     */
    public function update(int $id, array $data): BankAccount
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($id, $data, $tenantId, $userId) {
            $account = BankAccount::query()
                ->where('tenant_id', $tenantId)
                ->findOrFail($id);

            $account->fill([
                'bank_code' => $data['bank_code'] ?? $account->bank_code,
                'bank_name' => $data['bank_name'] ?? $account->bank_name,
                'account_number' => $data['account_number'] ?? $account->account_number,
                'account_holder' => $data['account_holder'] ?? $account->account_holder,
                'account_name' => $data['account_name'] ?? $account->account_name,
                'status' => $data['status'] ?? $account->status,
                'assigned_user_id' => $data['assigned_user_id'] ?? $account->assigned_user_id,
                'updated_by' => $userId,
            ]);

            $account->save();

            return $account->fresh();
        });
    }

    /**
     * 계좌 삭제
     */
    public function destroy(int $id): bool
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($id, $tenantId, $userId) {
            $account = BankAccount::query()
                ->where('tenant_id', $tenantId)
                ->findOrFail($id);

            // 대표계좌 삭제 시 다른 계좌를 대표로 설정
            if ($account->is_primary) {
                $nextPrimary = BankAccount::where('tenant_id', $tenantId)
                    ->where('id', '!=', $id)
                    ->where('status', 'active')
                    ->first();

                if ($nextPrimary) {
                    $nextPrimary->is_primary = true;
                    $nextPrimary->save();
                }
            }

            $account->deleted_by = $userId;
            $account->save();
            $account->delete();

            return true;
        });
    }

    /**
     * 계좌 상태 토글 (사용/정지)
     */
    public function toggleStatus(int $id): BankAccount
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($id, $tenantId, $userId) {
            $account = BankAccount::query()
                ->where('tenant_id', $tenantId)
                ->findOrFail($id);

            $account->toggleStatus();
            $account->updated_by = $userId;
            $account->save();

            return $account;
        });
    }

    /**
     * 대표계좌 설정
     */
    public function setPrimary(int $id): BankAccount
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($id, $tenantId, $userId) {
            // 기존 대표계좌 해제
            BankAccount::where('tenant_id', $tenantId)
                ->where('is_primary', true)
                ->update(['is_primary' => false]);

            // 새 대표계좌 설정
            $account = BankAccount::query()
                ->where('tenant_id', $tenantId)
                ->findOrFail($id);

            $account->is_primary = true;
            $account->updated_by = $userId;
            $account->save();

            return $account;
        });
    }

    /**
     * 활성 계좌 목록 조회 (셀렉트박스용)
     */
    public function getActiveAccounts(): array
    {
        $tenantId = $this->tenantId();

        return BankAccount::query()
            ->where('tenant_id', $tenantId)
            ->where('status', 'active')
            ->orderByDesc('is_primary')
            ->orderBy('account_name')
            ->get(['id', 'account_name', 'bank_name', 'account_number', 'is_primary'])
            ->map(function ($account) {
                return [
                    'id' => $account->id,
                    'account_name' => $account->account_name,
                    'bank_name' => $account->bank_name,
                    'display_number' => $account->getMaskedAccountNumber(),
                    'is_primary' => $account->is_primary,
                ];
            })
            ->toArray();
    }
}
