<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Support\ApiResponse;
use App\Support\Money;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

final class SubscriptionPlanController extends Controller
{
    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:2000'],
            'price_amount' => ['required', 'string', 'regex:/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/'],
            'price_currency' => ['required', 'string', 'in:USD'],
            'pay_currency' => ['required', 'string', 'max:20'],
            'interval' => ['required', 'in:day,week,month,year'],
            'interval_count' => ['nullable', 'integer', 'min:1', 'max:365'],
            'metadata' => ['nullable', 'array'],
        ]);

        $asset = Asset::where('code', strtoupper($data['pay_currency']))->where('enabled', true)->first();
        if (! $asset) {
            return ApiResponse::error('UNSUPPORTED_CURRENCY', 'The requested asset or network is not enabled.', 422);
        }

        $plan = DB::table('subscription_plans')->insertGetId([
            'public_id' => 'plan_'.Str::ulid(),
            'merchant_id' => $request->attributes->get('merchant')->id,
            'environment' => $request->attributes->get('environment'),
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'price_amount_minor' => Money::toMinor($data['price_amount'], 2),
            'price_currency' => strtoupper($data['price_currency']),
            'pay_currency' => strtoupper($data['pay_currency']),
            'interval' => $data['interval'],
            'interval_count' => $data['interval_count'] ?? 1,
            'status' => 'active',
            'metadata' => json_encode($data['metadata'] ?? [], JSON_UNESCAPED_SLASHES),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return ApiResponse::success($this->resource(DB::table('subscription_plans')->where('id', $plan)->first()), 201);
    }

    public function index(Request $request)
    {
        $plans = DB::table('subscription_plans')
            ->where('merchant_id', $request->attributes->get('merchant')->id)
            ->where('environment', $request->attributes->get('environment'))
            ->latest('id')
            ->get()
            ->map(fn ($plan) => $this->resource($plan));

        return ApiResponse::success($plans);
    }

    private function resource(object $plan): array
    {
        return [
            'id' => $plan->public_id,
            'name' => $plan->name,
            'description' => $plan->description,
            'price_amount' => number_format($plan->price_amount_minor / 100, 2, '.', ''),
            'price_currency' => $plan->price_currency,
            'pay_currency' => $plan->pay_currency,
            'interval' => $plan->interval,
            'interval_count' => (int) $plan->interval_count,
            'status' => $plan->status,
            'metadata' => json_decode($plan->metadata ?? '[]', true) ?: [],
            'created_at' => $plan->created_at,
        ];
    }
}
