const { withAndroidManifest, withDangerousMod } = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');

const FOREGROUND_SERVICE_PERMISSION = 'android.permission.FOREGROUND_SERVICE';
const FOREGROUND_SERVICE_DATA_SYNC = 'android.permission.FOREGROUND_SERVICE_DATA_SYNC';

/**
 * Expo Config Plugin：为 Android 添加前台服务保活
 * 
 * 功能：
 * 1. 添加 FOREGROUND_SERVICE 相关权限
 * 2. 在 AndroidManifest 中声明 Service
 * 3. 生成 Kotlin 原生服务代码
 * 4. 生成 React Native Bridge 模块
 * 
 * 参考：Element Android 的 GuardAndroidService
 */
const withForegroundService = (config, options = {}) => {
  const {
    notificationTitle = '萝卜社区',
    notificationBody = '正在后台同步消息',
    notificationIcon = 'ic_notification',
    channelId = 'carrot_sync_foreground',
    channelName = '消息同步',
  } = options;

  // 1. 添加权限和 Service 声明到 AndroidManifest
  config = withAndroidManifest(config, (config) => {
    const manifest = config.modResults;
    
    // 添加权限声明
    const permissions = [
      FOREGROUND_SERVICE_PERMISSION,
      FOREGROUND_SERVICE_DATA_SYNC,
    ];
    
    permissions.forEach((permission) => {
      const existingPermission = manifest.manifest['uses-permission']?.find(
        (p) => p.$['android:name'] === permission
      );
      if (!existingPermission) {
        if (!manifest.manifest['uses-permission']) {
          manifest.manifest['uses-permission'] = [];
        }
        manifest.manifest['uses-permission'].push({
          $: { 'android:name': permission },
        });
      }
    });

    // 添加 Service 声明
    if (!manifest.manifest.application[0].service) {
      manifest.manifest.application[0].service = [];
    }
    
    const existingService = manifest.manifest.application[0].service.find(
      (s) => s.$['android:name'] === '.SyncForegroundService'
    );
    
    if (!existingService) {
      manifest.manifest.application[0].service.push({
        $: {
          'android:name': '.SyncForegroundService',
          'android:enabled': 'true',
          'android:exported': 'false',
          'android:foregroundServiceType': 'dataSync',
        },
      });
    }

    return config;
  });

  // 2. 生成 Kotlin 原生代码
  config = withDangerousMod(config, [
    'android',
    async (config) => {
      const projectRoot = config.modRequest.projectRoot;
      const packageName = config.android.package;
      const kotlinPath = path.join(
        projectRoot,
        'android/app/src/main/java',
        packageName.replace(/\./g, '/')
      );

      // 确保目录存在
      if (!fs.existsSync(kotlinPath)) {
        fs.mkdirSync(kotlinPath, { recursive: true });
      }

      // 生成 SyncForegroundService.kt
      const serviceCode = generateServiceCode(packageName, {
        notificationTitle,
        notificationBody,
        notificationIcon,
        channelId,
        channelName,
      });
      
      fs.writeFileSync(
        path.join(kotlinPath, 'SyncForegroundService.kt'),
        serviceCode
      );

      // 生成 ForegroundServiceModule.kt (React Native Bridge)
      const moduleCode = generateModuleCode(packageName);
      fs.writeFileSync(
        path.join(kotlinPath, 'ForegroundServiceModule.kt'),
        moduleCode
      );

      // 生成 ForegroundServicePackage.kt
      const packageCode = generatePackageCode(packageName);
      fs.writeFileSync(
        path.join(kotlinPath, 'ForegroundServicePackage.kt'),
        packageCode
      );

      // 修改 MainApplication.kt 注册模块
      const mainAppPath = path.join(kotlinPath, 'MainApplication.kt');
      if (fs.existsSync(mainAppPath)) {
        let content = fs.readFileSync(mainAppPath, 'utf-8');
        
        // 添加 import
        if (!content.includes('ForegroundServicePackage')) {
          content = content.replace(
            /package .*\n/,
            `$&\nimport ${packageName}.ForegroundServicePackage\n`
          );
        }
        
        // 在 packages 列表中添加
        if (!content.includes('ForegroundServicePackage()')) {
          // 查找 PackageList(this).packages.apply 块
          content = content.replace(
            /(PackageList\(this\)\.packages\.apply\s*\{)/,
            `$1\n          // 前台服务模块\n          add(ForegroundServicePackage())`
          );
        }
        
        fs.writeFileSync(mainAppPath, content);
      }

      // 创建通知图标目录和文件
      const drawablePath = path.join(projectRoot, 'android/app/src/main/res/drawable');
      if (!fs.existsSync(drawablePath)) {
        fs.mkdirSync(drawablePath, { recursive: true });
      }
      
      const iconPath = path.join(drawablePath, 'ic_notification.xml');
      if (!fs.existsSync(iconPath)) {
        fs.writeFileSync(iconPath, generateNotificationIcon());
      }

      return config;
    },
  ]);

  return config;
};

/**
 * 生成前台服务 Kotlin 代码
 */
function generateServiceCode(packageName, options) {
  const { notificationTitle, notificationBody, notificationIcon, channelId, channelName } = options;
  
  return `package ${packageName}

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat

/**
 * 前台同步服务
 * 
 * 在通知栏显示常驻通知，防止应用进程被系统杀死
 * 类似 Element Android 的 GuardAndroidService 和 V2Ray 的保活机制
 */
class SyncForegroundService : Service() {

    companion object {
        const val NOTIFICATION_ID = 1001
        const val CHANNEL_ID = "${channelId}"
        const val CHANNEL_NAME = "${channelName}"
        
        const val ACTION_START = "${packageName}.foreground.START"
        const val ACTION_STOP = "${packageName}.foreground.STOP"
        const val ACTION_UPDATE = "${packageName}.foreground.UPDATE"
        
        const val EXTRA_TITLE = "title"
        const val EXTRA_BODY = "body"

        /**
         * 启动前台服务
         */
        fun start(context: Context, title: String = "${notificationTitle}", body: String = "${notificationBody}") {
            val intent = Intent(context, SyncForegroundService::class.java).apply {
                action = ACTION_START
                putExtra(EXTRA_TITLE, title)
                putExtra(EXTRA_BODY, body)
            }
            try {
                ContextCompat.startForegroundService(context, intent)
            } catch (e: Exception) {
                android.util.Log.e("SyncForegroundService", "启动前台服务失败", e)
            }
        }

        /**
         * 停止前台服务
         */
        fun stop(context: Context) {
            val intent = Intent(context, SyncForegroundService::class.java).apply {
                action = ACTION_STOP
            }
            context.startService(intent)
        }

        /**
         * 更新通知内容
         */
        fun update(context: Context, title: String, body: String) {
            val intent = Intent(context, SyncForegroundService::class.java).apply {
                action = ACTION_UPDATE
                putExtra(EXTRA_TITLE, title)
                putExtra(EXTRA_BODY, body)
            }
            context.startService(intent)
        }
    }

    private var notificationTitle: String = "${notificationTitle}"
    private var notificationBody: String = "${notificationBody}"

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START -> {
                notificationTitle = intent.getStringExtra(EXTRA_TITLE) ?: "${notificationTitle}"
                notificationBody = intent.getStringExtra(EXTRA_BODY) ?: "${notificationBody}"
                startForegroundCompat()
            }
            ACTION_STOP -> {
                stopForegroundCompat()
                stopSelf()
            }
            ACTION_UPDATE -> {
                notificationTitle = intent.getStringExtra(EXTRA_TITLE) ?: notificationTitle
                notificationBody = intent.getStringExtra(EXTRA_BODY) ?: notificationBody
                updateNotification()
            }
        }
        // START_STICKY: 服务被杀后自动重启
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? = null

    /**
     * 启动前台服务（兼容 Android Q+）
     */
    private fun startForegroundCompat() {
        val notification = buildNotification()
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startForeground(
                NOTIFICATION_ID,
                notification,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
            )
        } else {
            startForeground(NOTIFICATION_ID, notification)
        }
    }

    /**
     * 停止前台服务（兼容 Android N+）
     */
    private fun stopForegroundCompat() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            stopForeground(STOP_FOREGROUND_REMOVE)
        } else {
            @Suppress("DEPRECATION")
            stopForeground(true)
        }
    }

    /**
     * 创建通知渠道
     */
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                CHANNEL_NAME,
                NotificationManager.IMPORTANCE_MIN  // 最低重要性，不打扰用户
            ).apply {
                description = "后台消息同步服务"
                setSound(null, null)
                setShowBadge(false)
                enableLights(false)
                enableVibration(false)
            }
            
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    /**
     * 构建通知
     */
    private fun buildNotification(): Notification {
        // 点击通知打开应用
        val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            launchIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(notificationTitle)
            .setContentText(notificationBody)
            .setSmallIcon(R.drawable.${notificationIcon})
            .setCategory(NotificationCompat.CATEGORY_SERVICE)
            .setPriority(NotificationCompat.PRIORITY_MIN)
            .setOngoing(true)  // 不可滑动清除
            .setShowWhen(false)
            .setContentIntent(pendingIntent)
            .build()
    }

    /**
     * 更新通知内容
     */
    private fun updateNotification() {
        val manager = getSystemService(NotificationManager::class.java)
        manager.notify(NOTIFICATION_ID, buildNotification())
    }
}
`;
}

/**
 * 生成 React Native Bridge 模块代码
 */
function generateModuleCode(packageName) {
  return `package ${packageName}

import android.content.Context
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise

/**
 * React Native Bridge: 前台服务控制模块
 */
class ForegroundServiceModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    override fun getName(): String = "ForegroundService"

    /**
     * 启动前台服务
     */
    @ReactMethod
    fun start(title: String, body: String, promise: Promise) {
        try {
            SyncForegroundService.start(reactApplicationContext, title, body)
            promise.resolve(true)
        } catch (e: Exception) {
            promise.reject("FOREGROUND_SERVICE_ERROR", e.message)
        }
    }

    /**
     * 停止前台服务
     */
    @ReactMethod
    fun stop(promise: Promise) {
        try {
            SyncForegroundService.stop(reactApplicationContext)
            promise.resolve(true)
        } catch (e: Exception) {
            promise.reject("FOREGROUND_SERVICE_ERROR", e.message)
        }
    }

    /**
     * 更新通知内容
     */
    @ReactMethod
    fun update(title: String, body: String, promise: Promise) {
        try {
            SyncForegroundService.update(reactApplicationContext, title, body)
            promise.resolve(true)
        } catch (e: Exception) {
            promise.reject("FOREGROUND_SERVICE_ERROR", e.message)
        }
    }
}
`;
}

/**
 * 生成 React Native Package 代码
 */
function generatePackageCode(packageName) {
  return `package ${packageName}

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class ForegroundServicePackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        return listOf(ForegroundServiceModule(reactContext))
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList()
    }
}
`;
}

/**
 * 生成通知图标 XML
 */
function generateNotificationIcon() {
  return `<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <!-- 背景圆 -->
    <path
        android:fillColor="#4CAF50"
        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"/>
    <!-- 对勾符号 -->
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>
`;
}

module.exports = withForegroundService;