<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\Workspace;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

/**
 * Mobile Privacy & Data endpoints.
 *
 * Wraps the existing GDPR features already implemented in the web app:
 *   • Article 20 — full data export (JSON)         [DataExportController::export]
 *   • Article 17 — schedule account deletion       [DataExportController::requestDeletion]
 *   • Account deactivation                         [DataExportController::deactivate]
 *   • Per-workspace data retention + consent flags [Livewire DataPrivacySettings]
 *
 * Mobile reads consent + retention settings, flips them on/off, requests an
 * export, schedules deletion, or deactivates the user's account.
 */
class PrivacyController extends Controller
{
    /**
     * GET /api/v1/mobile/privacy
     * Read the current workspace's privacy settings + the user's deletion
     * status and the export entry-point URL.
     */
    public function show(Request $request): JsonResponse
    {
        $user = $request->user();
        $workspace = $user->active_workspace_id
            ? Workspace::find($user->active_workspace_id)
            : null;

        $settings = $workspace?->settings ?? [];

        return response()->json([
            'workspace' => $workspace ? [
                'id'   => $workspace->id,
                'name' => $workspace->name,
            ] : null,
            'retention' => [
                'conversation_days' => (int) ($settings['conversation_retention'] ?? 90),
                'contact_days'      => (int) ($settings['contact_retention'] ?? 365),
            ],
            'consent' => [
                'ai_training'         => (bool) ($settings['ai_training_consent'] ?? true),
                'analytics'           => (bool) ($settings['analytics_consent'] ?? true),
                'third_party_sharing' => (bool) ($settings['third_party_sharing'] ?? false),
            ],
            'rights' => [
                'export_url'           => url('/data/export'),
                'export_method'        => 'GET',
                'deletion_requested'   => (bool) $user->deletion_requested_at,
                'deletion_requested_at' => $user->deletion_requested_at?->toIso8601String(),
                'deletion_grace_days'  => 30,
            ],
            'roles' => [
                'is_workspace_admin' => in_array($user->workspaceRole($workspace?->id) ?? '', ['owner', 'admin'], true),
            ],
        ]);
    }

    /**
     * PUT /api/v1/mobile/privacy
     * Update the workspace-level retention + consent settings.
     * Only workspace owners / admins can change these.
     */
    public function update(Request $request): JsonResponse
    {
        $user = $request->user();
        $workspace = $user->active_workspace_id
            ? Workspace::find($user->active_workspace_id)
            : null;

        if (!$workspace) {
            return response()->json(['message' => 'No active workspace.'], 422);
        }

        $role = $user->workspaceRole($workspace->id);
        if (!in_array($role, ['owner', 'admin'], true)) {
            return response()->json(['message' => 'Only workspace owners and admins can change privacy settings.'], 403);
        }

        $validator = Validator::make($request->all(), [
            'conversation_retention_days' => ['sometimes', 'integer', 'in:30,60,90,180,365,730,0'],
            'contact_retention_days'      => ['sometimes', 'integer', 'in:90,180,365,730,1825,0'],
            'ai_training_consent'         => ['sometimes', 'boolean'],
            'analytics_consent'           => ['sometimes', 'boolean'],
            'third_party_sharing'         => ['sometimes', 'boolean'],
        ]);
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $settings = $workspace->settings ?? [];
        $payload = $validator->validated();

        if (array_key_exists('conversation_retention_days', $payload)) {
            $settings['conversation_retention'] = (string) $payload['conversation_retention_days'];
        }
        if (array_key_exists('contact_retention_days', $payload)) {
            $settings['contact_retention'] = (string) $payload['contact_retention_days'];
        }
        foreach (['ai_training_consent', 'analytics_consent', 'third_party_sharing'] as $key) {
            if (array_key_exists($key, $payload)) {
                $settings[$key] = (bool) $payload[$key];
            }
        }

        $workspace->update(['settings' => $settings]);

        return $this->show($request);
    }

    /**
     * POST /api/v1/mobile/privacy/export
     * Returns the URL the mobile app should open (web download — streams the
     * full GDPR JSON export, audit-logged server-side). Same behaviour as
     * the web Settings > Privacy > Export My Data button.
     */
    public function export(Request $request): JsonResponse
    {
        $user = $request->user();
        $workspace = $user->active_workspace_id
            ? Workspace::find($user->active_workspace_id)
            : null;

        $role = $workspace ? $user->workspaceRole($workspace->id) : null;
        if (!in_array($role, ['owner', 'admin'], true)) {
            return response()->json(['message' => 'Only workspace owners and admins can export data.'], 403);
        }

        // The actual streaming export is served by DataExportController@export
        // on the web side (authenticated session). Mobile receives a URL and
        // opens it in an external browser tab. We don't stream JSON through
        // the bearer-token API because mobile clients can't reliably handle
        // multi-hundred-MB streamed downloads in-app.
        return response()->json([
            'message'    => 'Open this URL in a browser to download your full data export.',
            'export_url' => url('/data/export'),
            'expires_in' => 600,
            'note'       => 'The export is generated on-demand and contains all your workspace data in a single JSON file.',
        ]);
    }

    /**
     * POST /api/v1/mobile/privacy/deletion-request
     * Schedule the current user's account for deletion (30-day grace).
     * Requires current password confirmation. Mirrors the web
     * DataExportController::requestDeletion flow.
     */
    public function requestDeletion(Request $request): JsonResponse
    {
        $user = $request->user();

        $validator = Validator::make($request->all(), [
            'confirmation' => ['required', 'string', 'in:DELETE'],
            'password'     => ['required', 'current_password'],
        ]);
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        DB::table('audit_logs')->insert([
            'auditable_type' => 'App\\Models\\User',
            'auditable_id'   => $user->id,
            'event'          => 'deletion_requested',
            'actor_type'     => 'user',
            'actor_id'       => $user->id,
            'actor_name'     => $user->name,
            'old_values'     => null,
            'new_values'     => json_encode(['deletion_requested_at' => now()->toIso8601String()]),
            'ip_address'     => $request->ip(),
            'user_agent'     => $request->userAgent(),
            'created_at'     => now(),
            'updated_at'     => now(),
        ]);

        $user->update([
            'deletion_requested_at' => now(),
            'status'                => 'pending_deletion',
        ]);

        Log::info('GDPR deletion requested via mobile API', [
            'user_id' => $user->id,
            'email'   => $user->email,
        ]);

        // Revoke ALL tokens so the user is logged out everywhere.
        $user->tokens()->delete();

        return response()->json([
            'message'                => 'Your account deletion has been scheduled. Your data will be permanently removed within 30 days. Sign in again before then to cancel.',
            'deletion_requested_at'  => $user->deletion_requested_at?->toIso8601String(),
            'deletion_grace_days'    => 30,
            'all_sessions_revoked'   => true,
        ]);
    }

    /**
     * POST /api/v1/mobile/privacy/deletion-cancel
     * Cancel a pending deletion request (must be authed — i.e., logged back
     * in before the grace period expires).
     */
    public function cancelDeletion(Request $request): JsonResponse
    {
        $user = $request->user();

        if (!$user->deletion_requested_at) {
            return response()->json(['message' => 'No deletion request is pending.'], 422);
        }

        DB::table('audit_logs')->insert([
            'auditable_type' => 'App\\Models\\User',
            'auditable_id'   => $user->id,
            'event'          => 'deletion_cancelled',
            'actor_type'     => 'user',
            'actor_id'       => $user->id,
            'actor_name'     => $user->name,
            'old_values'     => json_encode(['deletion_requested_at' => $user->deletion_requested_at?->toIso8601String()]),
            'new_values'     => null,
            'ip_address'     => $request->ip(),
            'user_agent'     => $request->userAgent(),
            'created_at'     => now(),
            'updated_at'     => now(),
        ]);

        $user->update([
            'deletion_requested_at' => null,
            'status'                => 'active',
        ]);

        return response()->json([
            'message' => 'Account deletion cancelled.',
        ]);
    }

    /**
     * POST /api/v1/mobile/privacy/deactivate
     * Soft-deactivate the user — login disabled, data preserved. User
     * contacts support to reactivate. Mirrors DataExportController::deactivate.
     */
    public function deactivate(Request $request): JsonResponse
    {
        $user = $request->user();

        DB::table('audit_logs')->insert([
            'auditable_type' => 'App\\Models\\User',
            'auditable_id'   => $user->id,
            'event'          => 'account_deactivated',
            'actor_type'     => 'user',
            'actor_id'       => $user->id,
            'actor_name'     => $user->name,
            'old_values'     => json_encode(['status' => $user->status]),
            'new_values'     => json_encode(['status' => 'suspended']),
            'ip_address'     => $request->ip(),
            'user_agent'     => $request->userAgent(),
            'created_at'     => now(),
            'updated_at'     => now(),
        ]);

        $user->update([
            'status'       => 'suspended',
            'suspended_at' => now(),
        ]);

        $user->tokens()->delete();

        return response()->json([
            'message' => 'Your account has been deactivated. Contact support to reactivate.',
            'all_sessions_revoked' => true,
        ]);
    }
}
