<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Concerns\ResolvesCurrentOrganization;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class ChannelIntegrationController extends Controller
{
    use ResolvesCurrentOrganization;

    public function index(Request $request): View
    {
        $organization = $this->currentOrganization($request);
        abort_if($organization === null, 404);
        abort_unless($this->currentUserCan($request, 'manage_channels'), 403);

        $integrations = $organization->channelIntegrations()
            ->get()
            ->keyBy('provider');

        return view('settings.channels', [
            'organization' => $organization,
            'integrations' => $integrations,
            'providers' => $this->providers(),
        ]);
    }

    public function update(Request $request, string $provider): RedirectResponse
    {
        $organization = $this->currentOrganization($request);
        abort_if($organization === null, 404);
        abort_unless($this->currentUserCan($request, 'manage_channels'), 403);

        abort_unless(array_key_exists($provider, $this->providers()), 404);

        $data = $request->validate([
            'enabled' => ['nullable', 'boolean'],
            'name' => ['nullable', 'string', 'max:120'],
            'external_id' => ['required', 'string', 'max:120'],
            'webhook_verify_token' => ['nullable', 'string', 'max:120'],
            'access_token' => ['nullable', 'string', 'max:4000'],
            'app_secret' => ['nullable', 'string', 'max:255'],
            'business_account_id' => ['nullable', 'string', 'max:120'],
            'phone_number_id' => ['nullable', 'string', 'max:120'],
            'page_id' => ['nullable', 'string', 'max:120'],
            'default_locale' => ['nullable', 'string', 'max:12'],
            'signature_verification' => ['nullable', Rule::in(['off', 'sha1', 'sha256'])],
        ]);

        $integration = $organization->channelIntegrations()
            ->firstOrNew(['provider' => $provider]);

        $settings = $integration->settings ?? [];
        $settings['business_account_id'] = $data['business_account_id'] ?? null;
        $settings['phone_number_id'] = $data['phone_number_id'] ?? null;
        $settings['page_id'] = $data['page_id'] ?? null;
        $settings['default_locale'] = $data['default_locale'] ?? 'bn';
        $settings['signature_verification'] = $data['signature_verification'] ?? 'off';

        $integration->fill([
            'name' => $data['name'] ?? null,
            'external_id' => $data['external_id'],
            'webhook_verify_token' => $data['webhook_verify_token'] ?: ($integration->webhook_verify_token ?: Str::random(48)),
            'enabled' => $request->boolean('enabled'),
            'settings' => array_filter($settings, fn (mixed $value): bool => $value !== null && $value !== ''),
            'connected_at' => Carbon::now(),
        ]);

        if (($data['access_token'] ?? '') !== '') {
            $integration->access_token = $data['access_token'];
        }

        if (($data['app_secret'] ?? '') !== '') {
            $integration->app_secret = $data['app_secret'];
        }

        $integration->save();

        return redirect()
            ->route('settings.channels.index')
            ->with('status', ucfirst($provider).' channel settings saved.');
    }

    public function destroy(Request $request, string $provider): RedirectResponse
    {
        $organization = $this->currentOrganization($request);
        abort_if($organization === null, 404);
        abort_unless($this->currentUserCan($request, 'manage_channels'), 403);

        $organization->channelIntegrations()
            ->where('provider', $provider)
            ->delete();

        return redirect()
            ->route('settings.channels.index')
            ->with('status', ucfirst($provider).' channel disconnected.');
    }

    /**
     * @return array<string, array{name: string, description: string, external_label: string, token_label: string}>
     */
    private function providers(): array
    {
        return [
            'facebook' => [
                'name' => 'Facebook Messenger',
                'description' => 'Receive Page inbox messages from Messenger into the shared support inbox and bot flow.',
                'external_label' => 'Facebook Page ID',
                'token_label' => 'Page access token',
            ],
            'whatsapp' => [
                'name' => 'WhatsApp Cloud API',
                'description' => 'Receive WhatsApp Business messages from Meta Cloud API into the shared support inbox and bot flow.',
                'external_label' => 'Phone number ID',
                'token_label' => 'WhatsApp access token',
            ],
        ];
    }
}
