<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\HelpArticle;
use App\Models\Ticket;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

/**
 * Mobile-app Help Center endpoints.
 *
 * Powers the in-app Help Center screen — popular topic cards (backed by
 * `help_articles`) and the "Submit a request" support form (backed by
 * `tickets` + `ticket_replies`).
 *
 * Topic categories shown as cards in the UI are derived from the
 * `help_articles.category` column. Tickets are scoped to the authed user.
 */
class HelpController extends Controller
{
    /**
     * Default UI palette + icon mapping for category cards. Used when the
     * underlying help_articles rows don't carry their own icon/color.
     */
    private const CATEGORY_DEFAULTS = [
        'getting_started' => ['label' => 'Getting started', 'icon' => 'rocket',    'color' => '#3b82f6', 'description' => 'Set up your inbox and first conversation'],
        'email_accounts'  => ['label' => 'Email accounts',  'icon' => 'mail',      'color' => '#ef4444', 'description' => 'Connect Gmail, Outlook or any IMAP mailbox'],
        'channels'        => ['label' => 'Channels',        'icon' => 'message',   'color' => '#22c55e', 'description' => 'WhatsApp, SMS, Telegram, Slack, Live Chat'],
        'campaigns'       => ['label' => 'Campaigns',       'icon' => 'megaphone', 'color' => '#f59e0b', 'description' => 'Email + SMS broadcasts with stats'],
        'workflows'       => ['label' => 'Workflows',       'icon' => 'workflow',  'color' => '#8b5cf6', 'description' => 'Automation, drip sequences, triggers'],
        'ai'              => ['label' => 'AI Assistant',    'icon' => 'sparkles',  'color' => '#8b5cf6', 'description' => 'Auto-reply, summaries, knowledge base'],
        'contacts'        => ['label' => 'Contacts',        'icon' => 'users',     'color' => '#14b8a6', 'description' => 'CRM, segments, lists, custom fields'],
        'billing'         => ['label' => 'Billing & plans', 'icon' => 'card',      'color' => '#f97316', 'description' => 'Subscriptions, invoices, plan limits'],
        'integrations'    => ['label' => 'Integrations',    'icon' => 'plug',      'color' => '#0ea5e9', 'description' => 'Stripe, Salesforce, HubSpot, Zapier'],
        'security'        => ['label' => 'Security',        'icon' => 'shield',    'color' => '#64748b', 'description' => 'Two-factor, data privacy, audit log'],
    ];

    /**
     * Allowed ticket categories shown in the "Type" dropdown on the form.
     */
    private const TICKET_TYPES = [
        'technical_issue'  => 'Technical Issue',
        'billing'          => 'Billing',
        'feature_request'  => 'Feature Request',
        'account_question' => 'Account Question',
        'integration_help' => 'Integration Help',
        'other'            => 'Other',
    ];

    // ── Topic cards (help_articles) ──────────────────────────────────

    /**
     * GET /api/v1/mobile/help/topics
     * Drives the "Browse popular topics" row of cards.
     */
    public function topics(Request $request): JsonResponse
    {
        // Aggregate published articles by category and pick a featured one
        // for the card excerpt. Categories with no articles are omitted.
        $rows = HelpArticle::query()
            ->where('is_published', true)
            ->select('category', DB::raw('COUNT(*) as article_count'))
            ->groupBy('category')
            ->orderByRaw("FIELD(category, 'getting_started', 'email_accounts', 'channels', 'campaigns', 'workflows', 'ai', 'contacts', 'billing', 'integrations', 'security')")
            ->get();

        $cards = $rows->map(function ($row) {
            $key = (string) $row->category;
            $defaults = self::CATEGORY_DEFAULTS[$key] ?? [
                'label'       => ucwords(str_replace('_', ' ', $key)),
                'icon'        => 'book',
                'color'       => '#6b7280',
                'description' => null,
            ];

            return [
                'key'           => $key,
                'label'         => $defaults['label'],
                'description'   => $defaults['description'],
                'icon'          => $defaults['icon'],
                'color'         => $defaults['color'],
                'article_count' => (int) $row->article_count,
            ];
        })->values()->all();

        return response()->json([
            'data' => $cards,
            'meta' => [
                'reply_eta_text' => 'Our team usually replies within 4 hours.',
            ],
        ]);
    }

    /**
     * GET /api/v1/mobile/help/topics/{category}/articles
     * Drill-down list of published articles in a category.
     */
    public function articles(Request $request, string $category): JsonResponse
    {
        $search = trim((string) $request->query('search', ''));

        $query = HelpArticle::query()
            ->where('is_published', true)
            ->where('category', $category)
            ->orderBy('sort_order');

        if ($search !== '') {
            $like = '%' . $search . '%';
            $query->where(function ($w) use ($like) {
                $w->where('title', 'like', $like)
                  ->orWhere('excerpt', 'like', $like)
                  ->orWhere('content', 'like', $like);
            });
        }

        $articles = $query->get(['id', 'slug', 'title', 'excerpt', 'category', 'icon', 'helpful_count', 'not_helpful_count', 'updated_at']);

        return response()->json([
            'data' => $articles->map(fn (HelpArticle $a) => [
                'id'                => $a->id,
                'slug'              => $a->slug,
                'title'             => $a->title,
                'excerpt'           => $a->excerpt,
                'category'          => $a->category,
                'icon'              => $a->icon,
                'helpful_count'     => (int) $a->helpful_count,
                'not_helpful_count' => (int) $a->not_helpful_count,
                'updated_at'        => $a->updated_at?->toIso8601String(),
            ])->values()->all(),
        ]);
    }

    /**
     * GET /api/v1/mobile/help/articles/{slug}
     * Single article (full content) for the reader screen.
     */
    public function article(Request $request, string $slug): JsonResponse
    {
        $article = HelpArticle::where('is_published', true)->where('slug', $slug)->first();
        if (!$article) {
            return response()->json(['message' => 'Article not found.'], 404);
        }

        return response()->json([
            'article' => [
                'id'                => $article->id,
                'slug'              => $article->slug,
                'title'             => $article->title,
                'content'           => $article->content,
                'excerpt'           => $article->excerpt,
                'category'          => $article->category,
                'icon'              => $article->icon,
                'helpful_count'     => (int) $article->helpful_count,
                'not_helpful_count' => (int) $article->not_helpful_count,
                'related_feature'   => $article->related_feature,
                'updated_at'        => $article->updated_at?->toIso8601String(),
            ],
        ]);
    }

    /**
     * POST /api/v1/mobile/help/articles/{slug}/feedback
     * Mirrors the web Livewire markHelpful / markNotHelpful with a 60-minute
     * dedupe cache per user per article so a single user can't farm the count.
     */
    public function feedback(Request $request, string $slug): JsonResponse
    {
        $vote = (string) $request->input('vote', '');
        if (!in_array($vote, ['helpful', 'not_helpful'], true)) {
            return response()->json([
                'message' => 'Invalid vote.',
                'errors'  => ['vote' => ['Allowed: helpful, not_helpful.']],
            ], 422);
        }

        $article = HelpArticle::where('is_published', true)->where('slug', $slug)->first();
        if (!$article) {
            return response()->json(['message' => 'Article not found.'], 404);
        }

        $userId = $request->user()->id;
        $cacheKey = ($vote === 'helpful' ? 'helpful_' : 'not_helpful_') . $userId . '_' . $article->id;
        if (\Illuminate\Support\Facades\Cache::has($cacheKey)) {
            return response()->json([
                'message' => 'Already recorded for this article.',
                'helpful_count'     => (int) $article->helpful_count,
                'not_helpful_count' => (int) $article->not_helpful_count,
            ]);
        }
        \Illuminate\Support\Facades\Cache::put($cacheKey, true, 60);

        $article->increment($vote === 'helpful' ? 'helpful_count' : 'not_helpful_count');
        $article->refresh();

        return response()->json([
            'message'           => 'Thanks for the feedback.',
            'helpful_count'     => (int) $article->helpful_count,
            'not_helpful_count' => (int) $article->not_helpful_count,
        ]);
    }

    // ── Support tickets ─────────────────────────────────────────────

    /**
     * GET /api/v1/mobile/help/tickets
     * List the current user's tickets. Newest first.
     */
    public function tickets(Request $request): JsonResponse
    {
        $user = $request->user();
        $perPage = (int) min(max((int) $request->query('per_page', 25), 5), 100);

        $query = Ticket::where('user_id', $user->id)->orderByDesc('created_at');

        if ($status = $request->query('status')) {
            if (in_array($status, ['open', 'in_progress', 'waiting', 'resolved', 'closed'], true)) {
                $query->where('status', $status);
            }
        }

        $page = $query->paginate($perPage);

        return response()->json([
            'data' => $page->getCollection()->map(fn (Ticket $t) => $this->shapeTicket($t))->all(),
            'meta' => [
                'current_page' => $page->currentPage(),
                'per_page'     => $page->perPage(),
                'total'        => $page->total(),
                'has_more'     => $page->hasMorePages(),
            ],
            'ticket_types'   => $this->ticketTypesList(),
            'reply_eta_text' => 'Our team usually replies within 4 hours.',
        ]);
    }

    /**
     * GET /api/v1/mobile/help/tickets/{id}
     * Full ticket detail + threaded replies.
     */
    public function ticket(Request $request, int $id): JsonResponse
    {
        $user = $request->user();
        $ticket = Ticket::with(['ticketReplies' => fn ($q) => $q->orderBy('created_at')])
            ->where('user_id', $user->id)
            ->find($id);

        if (!$ticket) {
            return response()->json(['message' => 'Ticket not found.'], 404);
        }

        return response()->json([
            'ticket'  => $this->shapeTicket($ticket),
            'replies' => $ticket->ticketReplies->map(fn ($r) => [
                'id'             => $r->id,
                'body'           => $r->body,
                'is_admin_reply' => (bool) $r->is_admin_reply,
                'created_at'     => $r->created_at?->toIso8601String(),
            ])->values()->all(),
        ]);
    }

    /**
     * POST /api/v1/mobile/help/tickets
     * Submit a new support ticket from the "Submit a request" form.
     */
    public function submitTicket(Request $request): JsonResponse
    {
        $user = $request->user();

        $validator = Validator::make($request->all(), [
            'name'     => ['nullable', 'string', 'max:255'],
            'mobile'   => ['nullable', 'string', 'max:50'],
            'email'    => ['nullable', 'email', 'max:255'],
            'type'     => ['required', 'string', \Illuminate\Validation\Rule::in(array_keys(self::TICKET_TYPES))],
            'priority' => ['required', 'string', 'in:low,medium,high'],
            'subject'  => ['nullable', 'string', 'max:255'],
            'message'  => ['required', 'string', 'max:10000'],
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $data = $validator->validated();

        // Map UI priority (low/medium/high) to the DB enum
        // (low/normal/high/urgent). "medium" → "normal" in the schema.
        $priorityMap = ['low' => 'low', 'medium' => 'normal', 'high' => 'high'];
        $priority    = $priorityMap[$data['priority']] ?? 'normal';

        $subject = $data['subject'] ?? null;
        if (!$subject) {
            // Auto-derive subject from the message's first line / 80 chars
            $first = trim(strtok($data['message'], "\n"));
            $subject = $first !== '' ? mb_substr($first, 0, 80) : self::TICKET_TYPES[$data['type']];
        }

        // Prepend the contact info to the body so the support team sees what
        // the user typed in the form (the columns name/mobile aren't on the
        // tickets table — we keep that info inline in the body).
        $contactBlock = [];
        if (!empty($data['name']))   $contactBlock[] = 'Name: ' . $data['name'];
        if (!empty($data['mobile'])) $contactBlock[] = 'Mobile: ' . $data['mobile'];
        if (!empty($data['email']))  $contactBlock[] = 'Email: ' . $data['email'];
        $contactPrefix = $contactBlock ? '[ Submitted via mobile app ]' . "\n" . implode("\n", $contactBlock) . "\n\n" : '';

        $ticket = Ticket::create([
            'user_id'      => $user->id,
            'workspace_id' => $user->active_workspace_id,
            'subject'      => $subject,
            'body'         => $contactPrefix . $data['message'],
            'status'       => 'open',
            'priority'     => $priority,
            'category'     => $data['type'],
        ]);

        return response()->json([
            'message' => 'Your request has been submitted. Our team usually replies within 4 hours.',
            'ticket'  => $this->shapeTicket($ticket),
        ], 201);
    }

    /**
     * POST /api/v1/mobile/help/tickets/{id}/replies
     * Add a reply from the user to one of their existing tickets.
     */
    public function reply(Request $request, int $id): JsonResponse
    {
        $user = $request->user();
        $ticket = Ticket::where('user_id', $user->id)->find($id);
        if (!$ticket) {
            return response()->json(['message' => 'Ticket not found.'], 404);
        }

        if ($ticket->status === 'closed') {
            return response()->json([
                'message' => 'This ticket is closed. Submit a new request to continue.',
                'errors'  => ['status' => ['Ticket is closed.']],
            ], 422);
        }

        $validator = Validator::make($request->all(), [
            'body' => ['required', 'string', 'max:10000'],
        ]);
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $reply = $ticket->ticketReplies()->create([
            'user_id'        => $user->id,
            'body'           => $request->input('body'),
            'is_admin_reply' => false,
        ]);

        // Bump status back to 'open' if it was 'waiting' (waiting on user)
        if ($ticket->status === 'waiting') {
            $ticket->update(['status' => 'open']);
        }

        return response()->json([
            'message' => 'Reply added.',
            'reply'   => [
                'id'             => $reply->id,
                'body'           => $reply->body,
                'is_admin_reply' => false,
                'created_at'     => $reply->created_at?->toIso8601String(),
            ],
            'ticket'  => $this->shapeTicket($ticket->fresh()),
        ], 201);
    }

    // ── Helpers ──────────────────────────────────────────────────────

    private function shapeTicket(Ticket $t): array
    {
        $priorityLabelMap = ['low' => 'Low', 'normal' => 'Medium', 'high' => 'High', 'urgent' => 'High'];

        return [
            'id'             => $t->id,
            'subject'        => $t->subject,
            'body'           => $t->body,
            'status'         => $t->status,
            'priority'       => $t->priority,
            'priority_label' => $priorityLabelMap[$t->priority] ?? 'Medium',
            'type'           => $t->category,
            'type_label'     => self::TICKET_TYPES[$t->category] ?? 'Other',
            'is_open'        => in_array($t->status, ['open', 'in_progress', 'waiting'], true),
            'replies_count'  => (int) $t->ticketReplies()->count(),
            'created_at'     => $t->created_at?->toIso8601String(),
            'updated_at'     => $t->updated_at?->toIso8601String(),
        ];
    }

    private function ticketTypesList(): array
    {
        $out = [];
        foreach (self::TICKET_TYPES as $key => $label) {
            $out[] = ['key' => $key, 'label' => $label];
        }
        return $out;
    }
}
