<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Business;
use App\Services\AuditService;
use App\Services\SecureFileService;
use App\Support\PhoneNumber;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class BusinessSettingsController extends Controller
{
    public function edit(): View
    {
        $business = Business::firstOrCreate(['id' => 1], ['name' => 'Microfinance']);
        return view('admin.settings.business', compact('business'));
    }

    public function update(Request $request, SecureFileService $files): RedirectResponse
    {
        $business = Business::firstOrCreate(['id' => 1], ['name' => 'Microfinance']);
        $before = $business->toArray();
        $oldPhoneCountryCode = PhoneNumber::sanitizeCountryCode($business->phone_country_code ?: PhoneNumber::DEFAULT_COUNTRY_CODE);

        if (! $request->has('phone_country_code')) {
            $request->merge(['phone_country_code' => $oldPhoneCountryCode]);
        }

        foreach ([
            'deadline_late_penalty_type' => $business->deadline_late_penalty_type ?: 'fixed',
            'deadline_late_penalty_value' => (string) ($business->deadline_late_penalty_value ?? '0'),
            'deadline_late_penalty_settlement' => $business->deadline_late_penalty_settlement ?: 'add_to_loan',
            'missed_schedule_penalty_type' => $business->missed_schedule_penalty_type ?: 'fixed',
            'missed_schedule_penalty_value' => (string) ($business->missed_schedule_penalty_value ?? '0'),
            'missed_schedule_penalty_settlement' => $business->missed_schedule_penalty_settlement ?: 'add_to_loan',
        ] as $key => $value) {
            if (! $request->has($key)) {
                $request->merge([$key => $value]);
            }
        }

        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'registration_number' => ['nullable', 'string', 'max:255'],
            'tin' => ['nullable', 'string', 'max:255'],
            'licence_details' => ['nullable', 'string', 'max:3000'],
            'address' => ['nullable', 'string', 'max:255'],
            'region' => ['nullable', 'string', 'max:255'],
            'district' => ['nullable', 'string', 'max:255'],
            'country' => ['required', 'string', 'max:255'],
            'phone_country_code' => ['required', 'regex:/^[1-9]\d{0,3}$/'],
            'phone' => ['nullable', 'string', 'max:50'],
            'phone_alt' => ['nullable', 'string', 'max:50'],
            'email' => ['nullable', 'email', 'max:255'],
            'website' => ['nullable', 'url', 'max:255'],
            'postal_address' => ['nullable', 'string', 'max:255'],
            'currency' => ['required', 'string', 'size:3'],
            'currency_symbol' => ['required', 'string', 'max:12'],
            'number_format' => ['required', Rule::in(['1,234.56', '1.234,56', '1234.56'])],
            'financial_year_start_month' => ['required', 'integer', 'between:1,12'],
            'accounting_period' => ['required', Rule::in(['monthly', 'quarterly', 'yearly'])],
            'default_interest_method' => ['required', Rule::in(['flat', 'reducing_balance', 'fixed_amount'])],
            'default_penalty_settings' => ['nullable', 'array'],
            'require_signed_contract_before_disbursement' => ['nullable', 'boolean'],
            'loan_approval_mode' => ['nullable', Rule::in(['approval_required','auto_authorized'])],
            'maker_checker_enabled' => ['nullable', 'boolean'],
            'manager_approval_threshold' => ['nullable', 'decimal:0,2', 'min:0', 'max:9999999999999999.99'],
            'top_up_eligibility_percentage' => ['nullable','numeric','decimal:0,2','between:1,100'],
            'payment_deadline_penalties_enabled' => ['nullable','boolean'],
            'deadline_late_penalty_type' => ['required', Rule::in(['fixed','percentage'])],
            'deadline_late_penalty_value' => ['required','decimal:0,6','min:0','max:9999999999999999.999999'],
            'deadline_late_penalty_settlement' => ['required', Rule::in(['add_to_loan','next_payment'])],
            'missed_schedule_penalty_type' => ['required', Rule::in(['fixed','percentage'])],
            'missed_schedule_penalty_value' => ['required','decimal:0,6','min:0','max:9999999999999999.999999'],
            'missed_schedule_penalty_settlement' => ['required', Rule::in(['add_to_loan','next_payment'])],
            'logo' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:4096'],
            'stamp' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:4096'],
        ]);

        foreach ([['deadline_late_penalty_type','deadline_late_penalty_value'],['missed_schedule_penalty_type','missed_schedule_penalty_value']] as [$type,$value]) {
            if ($data[$type] === 'percentage' && (float) $data[$value] > 1000) {
                throw ValidationException::withMessages([$value => 'Percentage penalties cannot exceed 1000%.']);
            }
        }

        $data['require_signed_contract_before_disbursement'] = $request->boolean('require_signed_contract_before_disbursement');
        $data['payment_deadline_penalties_enabled'] = $request->has('payment_deadline_penalties_enabled')
            ? $request->boolean('payment_deadline_penalties_enabled')
            : (bool) $business->payment_deadline_penalties_enabled;
        $data['loan_approval_mode'] = $data['loan_approval_mode'] ?? $business->loan_approval_mode ?? 'approval_required';
        $data['maker_checker_enabled'] = $request->has('maker_checker_enabled') ? $request->boolean('maker_checker_enabled') : (bool) $business->maker_checker_enabled;
        $data['manager_approval_threshold'] = $request->has('manager_approval_threshold')
            ? (blank($data['manager_approval_threshold'] ?? null) ? null : $data['manager_approval_threshold'])
            : $business->manager_approval_threshold;
        $data['top_up_eligibility_percentage'] = $request->has('top_up_eligibility_percentage')
            ? (string) $data['top_up_eligibility_percentage']
            : (string) ($business->top_up_eligibility_percentage ?? '70.00');
        unset($data['logo'], $data['stamp']);

        if ($request->hasFile('logo')) {
            $files->delete($business->logo_path);
            $data['logo_path'] = $files->store($request->file('logo'), "business/{$business->id}/branding");
        }

        if ($request->hasFile('stamp')) {
            $files->delete($business->stamp_path);
            $data['stamp_path'] = $files->store($request->file('stamp'), "business/{$business->id}/branding");
        }

        $newPhoneCountryCode = PhoneNumber::sanitizeCountryCode($data['phone_country_code']);
        $business->update($data);
        PhoneNumber::rebaseStoredNumbers($oldPhoneCountryCode, $newPhoneCountryCode);

        AuditService::record('business.settings.updated', $business, $before, $business->fresh()->toArray());
        return back()->with('success', 'Business settings updated.');
    }
}
