<?php

namespace App\Http\Controllers\Tenant;

use App\Http\Controllers\Controller;
use App\Models\SavingsProduct;
use App\Services\ActivityLogger;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class SavingsProductController extends Controller
{
    public function store(Request $request): RedirectResponse
    {
        $product = SavingsProduct::create($this->validated($request));

        ActivityLogger::log('savings_product_created', 'Savings product '.$product->name.' created.', $product);

        return back()->with('status', 'Savings product created.');
    }

    public function update(Request $request, SavingsProduct $product): RedirectResponse
    {
        $product->update($this->validated($request, $product));

        ActivityLogger::log('savings_product_updated', 'Savings product '.$product->name.' updated.', $product);

        return back()->with('status', 'Savings product updated.');
    }

    public function destroy(SavingsProduct $product): RedirectResponse
    {
        if (! $product->accounts()->exists()) {
            $name = $product->name;
            $product->delete();

            ActivityLogger::log('savings_product_deleted', 'Savings product '.$name.' deleted.');

            return back()->with('status', 'Savings product deleted.');
        }

        $product->update(['is_active' => false, 'allow_member_create' => false]);
        ActivityLogger::log('savings_product_disabled', 'Savings product '.$product->name.' disabled because accounts already use it.', $product);

        return back()->with('status', 'Savings product disabled because accounts already use it.');
    }

    private function validated(Request $request, ?SavingsProduct $product = null): array
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255', Rule::unique('savings_products')->where('tenant_id', $request->user()->tenant_id)->ignore($product)],
            'type' => ['required', Rule::in(array_keys(SavingsProduct::TYPES))],
            'description' => ['nullable', 'string', 'max:1000'],
            'account_number_prefix' => ['nullable', 'string', 'max:20', 'regex:/^[A-Za-z0-9]+$/'],
            'interest_rate' => ['required', 'numeric', 'min:0'],
            'minimum_opening_balance' => ['required', 'numeric', 'min:0'],
            'minimum_balance' => ['required', 'numeric', 'min:0'],
            'processing_fee_type' => ['required', Rule::in(array_keys(SavingsProduct::PROCESSING_FEE_TYPES))],
            'processing_fee_value' => ['nullable', 'numeric', 'min:0'],
            'processing_fee_timing' => ['required', Rule::in(array_keys(SavingsProduct::PROCESSING_FEE_TIMINGS))],
            'contribution_frequency' => ['nullable', Rule::in(array_keys(SavingsProduct::CONTRIBUTION_FREQUENCIES))],
            'duration_days' => ['nullable', 'integer', 'min:1', 'max:3650'],
            'withdrawal_policy' => ['required', Rule::in(array_keys(SavingsProduct::WITHDRAWAL_POLICIES))],
            'allow_member_create' => ['nullable', 'boolean'],
            'show_on_member_portal' => ['nullable', 'boolean'],
            'show_on_public_website' => ['nullable', 'boolean'],
            'is_active' => ['nullable', 'boolean'],
        ]);

        foreach (['allow_member_create', 'show_on_member_portal', 'show_on_public_website', 'is_active'] as $field) {
            $validated[$field] = $request->has($field)
                ? $request->boolean($field)
                : (bool) ($product?->{$field} ?? true);
        }

        if ($validated['type'] === 'regular') {
            $validated['contribution_frequency'] = null;
            $validated['duration_days'] = null;
        }

        if ($validated['type'] !== 'regular' && blank($validated['contribution_frequency'] ?? null)) {
            $validated['contribution_frequency'] = 'monthly';
        }

        if (($validated['processing_fee_type'] ?? 'fixed') === 'contribution_amount') {
            $validated['processing_fee_value'] = 0;
        } else {
            $validated['processing_fee_value'] = $validated['processing_fee_value'] ?? 0;
        }

        if ((float) ($validated['processing_fee_value'] ?? 0) <= 0 && ($validated['processing_fee_type'] ?? 'fixed') !== 'contribution_amount') {
            $validated['processing_fee_timing'] = 'manual';
        }

        $validated['account_number_prefix'] = filled($validated['account_number_prefix'] ?? null)
            ? strtoupper($validated['account_number_prefix'])
            : $this->defaultPrefixForType($validated['type']);
        $validated['contribution_amount'] = null;

        return $validated;
    }

    private function defaultPrefixForType(string $type): string
    {
        return match ($type) {
            'target' => 'TSA',
            'thrift_isusu' => 'ISU',
            'cooperative' => 'COP',
            default => 'SAV',
        };
    }
}
