<?php

namespace App\Http\Controllers\admin;

use App\Constants\HttpStatus;
use App\Http\Controllers\Controller;
use App\Services\BalanceLogService;
use App\Services\ManualAuditService;
use Exception;
use Illuminate\Validation\ValidationException;

class ManualAudit extends Controller
{
    private const AMOUNT_PATTERN = '/^\d{1,20}(?:\.\d{1,10})?$/';

    public function index()
    {
        try {
            $params = request()->validate([
                'page' => ['nullable', 'integer', 'min:1'],
                'limit' => ['nullable', 'integer', 'min:1', 'max:200'],
                'member_id' => ['nullable', 'string', 'max:64'],
                'first_name' => ['nullable', 'string', 'max:100'],
                'transaction_type' => ['nullable', 'string', 'in:credit,debit'],
                'change_type' => ['nullable', 'string', 'in:' . implode(',', array_merge(
                    BalanceLogService::$manualRecharge,
                    [ManualAuditService::DEBIT_CHANGE_TYPE]
                ))],
                'status' => ['nullable', 'integer', 'in:0,1'],
                'start_date' => ['nullable', 'date_format:Y-m-d', 'required_with:end_date'],
                'end_date' => ['nullable', 'date_format:Y-m-d', 'required_with:start_date', 'after_or_equal:start_date'],
            ]);

            return $this->success(ManualAuditService::list($params));
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
        }
    }

    public function detail()
    {
        try {
            $params = request()->validate([
                'id' => ['required', 'integer', 'min:1'],
            ]);

            return $this->success(ManualAuditService::detail((int)$params['id']));
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
        }
    }

    public function topUp()
    {
        try {
            $params = request()->validate([
                'request_id' => ['required', 'uuid'],
                'member_id' => ['required', 'string', 'max:64'],
                'change_type' => ['required', 'string', 'in:' . implode(',', BalanceLogService::$manualRecharge)],
                'amount' => ['required', 'numeric', 'min:0.01', 'regex:' . self::AMOUNT_PATTERN],
                'remark' => ['nullable', 'string', 'max:255'],
            ]);
            $remark = trim((string)($params['remark'] ?? ''));
            $result = ManualAuditService::credit(
                (string)$params['request_id'],
                (int)request()->user->id,
                (string)$params['member_id'],
                (string)$params['amount'],
                (string)$params['change_type'],
                $remark
            );

            return $this->adjustmentResponse($result);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
        }
    }

    public function debit()
    {
        try {
            $params = request()->validate([
                'request_id' => ['required', 'uuid'],
                'member_id' => ['required', 'string', 'max:64'],
                'amount' => ['required', 'numeric', 'min:0.01', 'regex:' . self::AMOUNT_PATTERN],
                'remark' => ['nullable', 'string', 'max:255'],
            ]);
            $remark = trim((string)($params['remark'] ?? ''));
            $result = ManualAuditService::debit(
                (string)$params['request_id'],
                (int)request()->user->id,
                (string)$params['member_id'],
                (string)$params['amount'],
                $remark
            );

            return $this->adjustmentResponse($result);
        } catch (ValidationException $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->validator->errors()->first());
        } catch (Exception $e) {
            return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
        }
    }

    private function adjustmentResponse(array $result)
    {
        if ((int)($result['status'] ?? ManualAuditService::STATUS_FAILED) !== ManualAuditService::STATUS_SUCCESS) {
            return $this->error(
                HttpStatus::CUSTOM_ERROR,
                (string)($result['failure_reason'] ?? '人工操作失败'),
                $result
            );
        }

        return $this->success($result);
    }
}
