<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\ChannelIntegration;
use App\Models\EmailAccount;
use App\Models\HelpArticle;
use App\Models\Language;
use App\Models\SystemSetting;
use App\Models\User;
use App\Models\Workspace;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * Mobile settings/profile summary for the Settings tab.
 *
 * The screen is summary-oriented rather than fully editable, so the payload
 * focuses on quick-read cards: profile, channel connectivity, billing, team
 * counts, preferences, and support entry points.
 */
class SettingsController extends Controller
{
    /**
     * GET /api/v1/mobile/settings
     */
    public function show(Request $request): JsonResponse
    {
        /** @var User $user */
        $user = $request->user();
        $workspace = $user->active_workspace_id
            ? Workspace::with(['subscription.plan'])->find($user->active_workspace_id)
            : null;

        $language = $this->resolveLanguage($user);

        return response()->json([
            'profile' => $this->profilePayload($user, $workspace),
            'channels' => $this->channelPayload((int) ($workspace?->id ?? 0)),
            'workspace' => $this->workspacePayload($workspace),
            'preferences' => [
                'language' => [
                    'code' => $language?->code ?? (string) ($user->language ?: $user->locale ?: 'en'),
                    'label' => $language?->name ?? $this->fallbackLanguageLabel($user->language ?: $user->locale),
                    'native_name' => $language?->native_name,
                ],
                'dark_mode' => [
                    // The current app manages theme client-side; there is no
                    // persisted server-side preference yet.
                    'managed_client_side' => true,
                    'value' => null,
                ],
            ],
            'support' => [
                'help_center' => [
                    'articles_count' => (int) HelpArticle::published()->count(),
                ],
                'contact_support' => [
                    'email' => SystemSetting::get('support_email', 'support@example.com'),
                    'phone' => SystemSetting::get('support_phone', ''),
                ],
            ],
            'actions' => [
                'logout_endpoint' => '/api/v1/auth/logout',
            ],
        ]);
    }

    private function profilePayload(User $user, ?Workspace $workspace): array
    {
        $subscription = $workspace?->subscription;
        $plan = $subscription?->plan;

        return [
            'id' => $user->id,
            'uuid' => $user->uuid,
            'name' => $user->name,
            'email' => $user->email,
            'avatar_url' => $user->avatar_path ? asset('storage/' . $user->avatar_path) : null,
            'initials' => $user->initials,
            'workspace_role' => $workspace ? $user->workspaceRole($workspace->id) : null,
            'workspace' => $workspace ? [
                'id' => $workspace->id,
                'name' => $workspace->name,
                'slug' => $workspace->slug,
            ] : null,
            'plan' => $plan ? [
                'name' => $plan->name,
                'slug' => $plan->slug,
                'badge' => trim($plan->name . ' plan'),
                'status' => $subscription?->status,
                'billing_cycle' => $subscription?->billing_cycle,
                'price' => $this->planPrice($plan, $subscription?->billing_cycle),
                'price_label' => $this->planPriceLabel($plan, $subscription?->billing_cycle),
            ] : null,
        ];
    }

    private function channelPayload(int $workspaceId): array
    {
        if ($workspaceId <= 0) {
            return [
                $this->emailChannelRow(0),
                $this->integrationChannelRow('whatsapp', 'WhatsApp Business', null),
                $this->integrationChannelRow('sms', 'SMS via Twilio', null),
                $this->integrationChannelRow('telegram', 'Telegram bot', null),
                $this->integrationChannelRow('slack', 'Slack', null),
            ];
        }

        $emailConnectedCount = (int) EmailAccount::where('workspace_id', $workspaceId)
            ->where('status', 'connected')
            ->count();

        // Slack was previously omitted from the whereIn — that's why Slack
        // never appeared in /api/v1/mobile/settings even when connected.
        // Listing all 4 integration channels keeps the response shape
        // identical to the web Settings overview.
        $integrations = ChannelIntegration::where('workspace_id', $workspaceId)
            ->whereIn('channel', ['whatsapp', 'sms', 'telegram', 'slack'])
            ->get()
            ->keyBy('channel');

        return [
            $this->emailChannelRow($emailConnectedCount),
            $this->integrationChannelRow('whatsapp', 'WhatsApp Business', $integrations->get('whatsapp')),
            $this->integrationChannelRow('sms', 'SMS via Twilio', $integrations->get('sms')),
            $this->integrationChannelRow('telegram', 'Telegram bot', $integrations->get('telegram')),
            $this->integrationChannelRow('slack', 'Slack', $integrations->get('slack')),
        ];
    }

    private function emailChannelRow(int $connectedCount): array
    {
        $connected = $connectedCount > 0;

        return [
            'key' => 'email',
            'label' => 'Email accounts',
            'status' => $connected ? 'connected' : 'not_connected',
            'connected' => $connected,
            'connected_count' => $connectedCount,
            'subtitle' => $connected ? $connectedCount . ' connected' : 'Not connected',
        ];
    }

    private function integrationChannelRow(string $key, string $label, ?ChannelIntegration $integration): array
    {
        $connected = $integration?->status === 'active';
        $detail = $connected ? $this->integrationDetail($key, $integration) : null;

        $row = [
            'key' => $key,
            'label' => $label,
            'status' => $connected ? 'connected' : 'not_connected',
            'connected' => $connected,
            'subtitle' => $connected ? ($detail ?: 'Connected') : 'Not connected',
        ];

        if (in_array($key, ['whatsapp', 'sms'], true)) {
            $row['phone_number'] = $detail;
        }

        if ($key === 'telegram') {
            $row['bot_username'] = $detail;
        }

        if ($key === 'slack') {
            // Selected Slack channel id (e.g. "C01ABC…"). Null when the
            // workspace connected Slack but hasn't picked a notification
            // channel yet — the mobile app should show a "Choose channel"
            // CTA in that case (mirrors the web Integrations modal).
            $row['slack_channel_id'] = $integration?->slack_channel_id;
        }

        return $row;
    }

    private function integrationDetail(string $channel, ChannelIntegration $integration): ?string
    {
        return match ($channel) {
            'whatsapp' => $this->cleanString(
                $integration->phone_number
                ?? data_get($integration->credentials, 'phone_number')
                ?? data_get($integration->credentials, 'phone_number_id')
            ),
            'sms' => $this->cleanString(
                $integration->phone_number
                ?? data_get($integration->credentials, 'phone_number')
            ),
            'telegram' => $this->cleanString(
                $integration->bot_username
                ?? data_get($integration->config, 'bot_username')
            ),
            'slack' => $this->cleanString(
                $integration->slack_channel_id
                ?? data_get($integration->credentials, 'team_name')
                ?? data_get($integration->credentials, 'slack_team_id')
            ),
            default => null,
        };
    }

    private function workspacePayload(?Workspace $workspace): array
    {
        $subscription = $workspace?->subscription;
        $plan = $subscription?->plan;
        $renewsAt = $subscription?->current_period_end;

        return [
            'id' => $workspace?->id,
            'name' => $workspace?->name,
            'team_members' => [
                'active_count' => $this->activeMemberCount($workspace),
                'invited_count' => $this->pendingInviteCount($workspace),
            ],
            'billing' => [
                'plan_name' => $plan?->name,
                'plan_slug' => $plan?->slug,
                'status' => $subscription?->status,
                'billing_cycle' => $subscription?->billing_cycle,
                'price' => $this->planPrice($plan, $subscription?->billing_cycle),
                'price_label' => $this->planPriceLabel($plan, $subscription?->billing_cycle),
                'renews_at' => $renewsAt?->toIso8601String(),
                'renews_label' => $renewsAt ? 'Renews ' . $renewsAt->format('M j') : null,
            ],
            'privacy' => [
                'export_enabled' => true,
                'delete_enabled' => true,
                'gdpr' => true,
            ],
        ];
    }

    private function activeMemberCount(?Workspace $workspace): int
    {
        if (!$workspace || !Schema::hasTable('workspace_members')) {
            return 0;
        }

        return (int) $workspace->members()
            ->wherePivot('status', 'active')
            ->count();
    }

    private function pendingInviteCount(?Workspace $workspace): int
    {
        if (!$workspace || !Schema::hasTable('workspace_invites')) {
            return 0;
        }

        return (int) DB::table('workspace_invites')
            ->where('workspace_id', $workspace->id)
            ->where('status', 'pending')
            ->count();
    }

    private function resolveLanguage(User $user): ?Language
    {
        $preferred = $this->cleanString($user->language ?: $user->locale);
        if (!$preferred) {
            return Language::getDefault();
        }

        $normalized = strtolower(str_replace('_', '-', $preferred));
        $base = explode('-', $normalized)[0] ?? $normalized;

        return Language::findByCode($preferred)
            ?? Language::findByCode($normalized)
            ?? Language::findByCode($base)
            ?? Language::getDefault();
    }

    private function fallbackLanguageLabel(?string $code): string
    {
        $normalized = strtolower(str_replace('_', '-', (string) $code));

        return match ($normalized) {
            'en', 'en-us' => 'English (US)',
            'en-gb' => 'English (UK)',
            default => strtoupper($normalized ?: 'en'),
        };
    }

    private function cleanString(mixed $value): ?string
    {
        $value = trim((string) ($value ?? ''));

        return $value !== '' ? $value : null;
    }

    private function planPrice(mixed $plan, ?string $billingCycle): ?float
    {
        if (!$plan) {
            return null;
        }

        return (float) ($billingCycle === 'yearly'
            ? ($plan->yearly_price ?? 0)
            : ($plan->monthly_price ?? 0));
    }

    private function planPriceLabel(mixed $plan, ?string $billingCycle): ?string
    {
        $price = $this->planPrice($plan, $billingCycle);
        if ($price === null) {
            return null;
        }

        $suffix = $billingCycle === 'yearly' ? '/yr' : '/mo';

        return '$' . rtrim(rtrim(number_format($price, 2, '.', ''), '0'), '.') . $suffix;
    }
}
