<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Services\BankAccountService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class BankAccountController extends Controller
{
    public function __construct(
        private BankAccountService $bankAccountService
    ) {}

    /**
     * 계좌 목록 조회
     */
    public function index(Request $request): JsonResponse|Response
    {
        $accounts = $this->bankAccountService->getAccounts(
            $request->all(),
            $request->integer('per_page', 15)
        );

        // HTMX 요청인 경우 HTML 반환
        if ($request->header('HX-Request')) {
            return response(view('finance.accounts.partials.table', compact('accounts')));
        }

        return response()->json([
            'success' => true,
            'data' => $accounts->items(),
            'meta' => [
                'current_page' => $accounts->currentPage(),
                'last_page' => $accounts->lastPage(),
                'per_page' => $accounts->perPage(),
                'total' => $accounts->total(),
            ],
        ]);
    }

    /**
     * 계좌 상세 조회
     */
    public function show(int $id): JsonResponse
    {
        $account = $this->bankAccountService->getAccountById($id);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => $account,
        ]);
    }

    /**
     * 계좌 생성
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'bank_code' => 'nullable|string|max:10',
            'bank_name' => 'required|string|max:50',
            'account_number' => 'required|string|max:30',
            'account_holder' => 'required|string|max:50',
            'account_name' => 'nullable|string|max:100',
            'account_type' => 'nullable|string|max:30',
            'balance' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|max:3',
            'opened_at' => 'nullable|date',
            'branch_name' => 'nullable|string|max:100',
            'memo' => 'nullable|string',
            'status' => 'nullable|string|in:active,inactive',
            'is_primary' => 'nullable|boolean',
            'sort_order' => 'nullable|integer|min:0',
        ]);

        // 기본값 설정
        $validated['status'] = $validated['status'] ?? 'active';
        $validated['account_name'] = $validated['account_name'] ?? $validated['bank_name'].' 계좌';

        $account = $this->bankAccountService->createAccount($validated);

        return response()->json([
            'success' => true,
            'message' => '계좌가 등록되었습니다.',
            'data' => $account,
        ], 201);
    }

    /**
     * 계좌 수정
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $account = $this->bankAccountService->getAccountById($id);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $validated = $request->validate([
            'bank_code' => 'nullable|string|max:10',
            'bank_name' => 'sometimes|required|string|max:50',
            'account_number' => 'sometimes|required|string|max:30',
            'account_holder' => 'nullable|string|max:50',
            'account_name' => 'nullable|string|max:100',
            'account_type' => 'nullable|string|max:30',
            'balance' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|max:3',
            'opened_at' => 'nullable|date',
            'branch_name' => 'nullable|string|max:100',
            'memo' => 'nullable|string',
            'status' => 'nullable|string|in:active,inactive',
            'is_primary' => 'nullable|boolean',
            'sort_order' => 'nullable|integer|min:0',
        ]);

        $account = $this->bankAccountService->updateAccount($account, $validated);

        return response()->json([
            'success' => true,
            'message' => '계좌가 수정되었습니다.',
            'data' => $account,
        ]);
    }

    /**
     * 계좌 삭제 (Soft Delete)
     */
    public function destroy(Request $request, int $id): JsonResponse|Response
    {
        $account = $this->bankAccountService->getAccountById($id);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $this->bankAccountService->deleteAccount($account);

        // HTMX 요청인 경우 갱신된 테이블 반환
        if ($request->header('HX-Request')) {
            $accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));

            return response(view('finance.accounts.partials.table', compact('accounts')));
        }

        return response()->json([
            'success' => true,
            'message' => '계좌가 삭제되었습니다.',
        ]);
    }

    /**
     * 계좌 복원
     */
    public function restore(Request $request, int $id): JsonResponse|Response
    {
        $account = $this->bankAccountService->getAccountById($id, withTrashed: true);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $this->bankAccountService->restoreAccount($account);

        // HTMX 요청인 경우 갱신된 테이블 반환
        if ($request->header('HX-Request')) {
            $accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));

            return response(view('finance.accounts.partials.table', compact('accounts')));
        }

        return response()->json([
            'success' => true,
            'message' => '계좌가 복원되었습니다.',
        ]);
    }

    /**
     * 계좌 영구 삭제
     */
    public function forceDelete(Request $request, int $id): JsonResponse|Response
    {
        $account = $this->bankAccountService->getAccountById($id, withTrashed: true);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $this->bankAccountService->forceDeleteAccount($account);

        // HTMX 요청인 경우 갱신된 테이블 반환
        if ($request->header('HX-Request')) {
            $accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));

            return response(view('finance.accounts.partials.table', compact('accounts')));
        }

        return response()->json([
            'success' => true,
            'message' => '계좌가 영구 삭제되었습니다.',
        ]);
    }

    /**
     * 활성/비활성 토글
     */
    public function toggleActive(Request $request, int $id): JsonResponse|Response
    {
        $account = $this->bankAccountService->getAccountById($id);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $account = $this->bankAccountService->toggleActive($account);

        // HTMX 요청인 경우 갱신된 테이블 반환
        if ($request->header('HX-Request')) {
            $accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));

            return response(view('finance.accounts.partials.table', compact('accounts')));
        }

        return response()->json([
            'success' => true,
            'message' => $account->status === 'active' ? '계좌가 활성화되었습니다.' : '계좌가 비활성화되었습니다.',
            'data' => $account,
        ]);
    }

    /**
     * 일괄 삭제
     */
    public function bulkDelete(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer|exists:bank_accounts,id',
        ]);

        $count = $this->bankAccountService->bulkDelete($validated['ids']);

        return response()->json([
            'success' => true,
            'message' => "{$count}개의 계좌가 삭제되었습니다.",
        ]);
    }

    /**
     * 일괄 복원
     */
    public function bulkRestore(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer',
        ]);

        $count = $this->bankAccountService->bulkRestore($validated['ids']);

        return response()->json([
            'success' => true,
            'message' => "{$count}개의 계좌가 복원되었습니다.",
        ]);
    }

    /**
     * 일괄 영구 삭제
     */
    public function bulkForceDelete(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer',
        ]);

        $count = $this->bankAccountService->bulkForceDelete($validated['ids']);

        return response()->json([
            'success' => true,
            'message' => "{$count}개의 계좌가 영구 삭제되었습니다.",
        ]);
    }

    /**
     * 모든 계좌 목록 (드롭다운용)
     */
    public function all(): JsonResponse
    {
        $accounts = $this->bankAccountService->getAllAccounts();

        return response()->json([
            'success' => true,
            'data' => $accounts,
        ]);
    }

    /**
     * 요약 통계
     */
    public function summary(): JsonResponse
    {
        $summary = $this->bankAccountService->getSummary();

        return response()->json([
            'success' => true,
            'data' => $summary,
        ]);
    }

    /**
     * 계좌의 거래내역 조회
     */
    public function transactions(Request $request, int $id): JsonResponse|Response
    {
        $account = $this->bankAccountService->getAccountById($id);

        if (! $account) {
            return response()->json([
                'success' => false,
                'message' => '계좌를 찾을 수 없습니다.',
            ], 404);
        }

        $transactions = $this->bankAccountService->getTransactions(
            $id,
            $request->all(),
            $request->integer('per_page', 20)
        );

        // HTMX 요청인 경우 HTML 반환
        if ($request->header('HX-Request')) {
            return response(view('finance.accounts.partials.transactions-table', compact('account', 'transactions')));
        }

        return response()->json([
            'success' => true,
            'data' => [
                'account' => $account,
                'transactions' => $transactions->items(),
            ],
            'meta' => [
                'current_page' => $transactions->currentPage(),
                'last_page' => $transactions->lastPage(),
                'per_page' => $transactions->perPage(),
                'total' => $transactions->total(),
            ],
        ]);
    }
}
