/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.accessibility.notification;

import static com.android.internal.accessibility.common.NotificationConstants.EXTRA_SOURCE;
import static com.android.internal.accessibility.common.NotificationConstants.SOURCE_START_SURVEY;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.android.settings.R;

/**
 * Helper class for creating and managing survey notifications.
 */
public class NotificationHelper {

    public static final String NOTIFICATION_CHANNEL_ID =
            "com.android.settings.accessibility.notification.SurveyNotification";

    // The base ID for notifications is derived from the bug component ID.
    // Page-specific notification IDs are generated by adding the respective pageId to this base.
    private static final int NOTIFICATION_ID_BASE = 751131;
    private static final int START_SURVEY_REQUEST_CODE = 1;

    private final Context mContext;
    private final NotificationManager mNotificationManager;

    /**
     * Constructs a new NotificationHelper.
     * <p>
     * Initializes the helper with the application context and gets the system's
     * NotificationManager service. It also ensures that the notification channel
     * for survey notifications is created if it doesn't already exist.
     * </p>
     *
     * @param context The context used to access system services and resources.
     */
    public NotificationHelper(@NonNull Context context) {
        mContext = context.getApplicationContext();
        mNotificationManager = mContext.getSystemService(NotificationManager.class);
        if (mNotificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
            final NotificationChannel channel = new NotificationChannel(
                    NOTIFICATION_CHANNEL_ID,
                    mContext.getString(R.string.accessibility_send_survey_notification_channel),
                    NotificationManager.IMPORTANCE_LOW);
            mNotificationManager.createNotificationChannel(channel);
        }
    }

    private PendingIntent createNotifyPendingIntent(Intent notifyIntent) {
        notifyIntent.putExtra(EXTRA_SOURCE, SOURCE_START_SURVEY);
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        return PendingIntent.getActivity(
                mContext,
                START_SURVEY_REQUEST_CODE,
                notifyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    }

    private Notification.Action createAction(PendingIntent pendingIntent, String actionText) {
        return new Notification.Action.Builder(
                /* icon= */ null,
                actionText,
                pendingIntent)
                .build();
    }

    private Notification.Builder createNotificationBuilder(String title, String text,
            PendingIntent notifyPendingIntent) {
        return new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_settings_24dp)
                .setContentIntent(notifyPendingIntent)
                .setFlag(Notification.FLAG_NO_CLEAR, true)
                .setAutoCancel(true);
    }

    private void showNotification(int notificationId, String title, String text,
            String actionText, Intent notifyIntent) {
        final PendingIntent contentPendingIntent = createNotifyPendingIntent(notifyIntent);
        final Notification.Action action = createAction(contentPendingIntent, actionText);
        final Notification notification =
                createNotificationBuilder(title, text, contentPendingIntent)
                        .addAction(action)
                        .build();
        mNotificationManager.notify(notificationId, notification);
    }

    /**
     * Determines the specific survey notification to show based on the page ID and displays it.
     *
     * @param pageId The ID of the settings page for which to show the survey.
     */
    public void cancelNotification(int pageId) {
        mNotificationManager.cancel(getNotificationId(pageId));
    }

    /**
     * Generates a notification ID based on a base ID and a page ID. This ensures that notifications
     * for different pages will have distinct IDs.
     *
     * @param pageId The unique identifier of the page for which to generate a notification ID.
     * @return A unique integer representing the notification ID for the given page.
     */
    @VisibleForTesting
    public int getNotificationId(int pageId) {
        return NOTIFICATION_ID_BASE + pageId;
    }

    /**
     * Determines the specific survey notification to show based on the page ID and displays it.
     *
     * @param pageId The ID of the settings page for which to show the survey.
     */
    public void showSurveyNotification(int pageId) {
        if (pageId == SettingsEnums.DARK_UI_SETTINGS) {
            final Intent settingsIntent = new Intent(Settings.ACTION_DARK_THEME_SETTINGS)
                    .setPackage(mContext.getPackageName());
            showNotification(
                    getNotificationId(pageId),
                    mContext.getString(R.string.dark_theme_survey_notification_title),
                    mContext.getString(R.string.dark_theme_survey_notification_summary),
                    mContext.getString(R.string.dark_theme_survey_notification_action),
                    settingsIntent
            );
        } else if (pageId == SettingsEnums.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION) {
            final Intent settingsIntent =
                    new Intent(Settings.ACTION_SCREEN_MAGNIFICATION_SETTINGS)
                            .setPackage(mContext.getPackageName());
            showNotification(
                    getNotificationId(pageId),
                    mContext.getString(R.string.magnification_survey_notification_title),
                    mContext.getString(R.string.magnification_survey_notification_summary),
                    mContext.getString(R.string.magnification_survey_notification_action),
                    settingsIntent
            );
        }
    }
}
