package ai.z.chat;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.webkit.MimeTypeMap;

import androidx.core.content.FileProvider;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@CapacitorPlugin(name = "FileManager")
public class FileManagerPlugin extends Plugin {

    @PluginMethod
    public void openFile(PluginCall call) {
        String path = call.getString("path", "");
        String mimeType = call.getString("mimeType", "");
        if (path.isEmpty()) {
            call.reject("No path provided");
            return;
        }

        File file = new File(path);
        if (!file.exists()) {
            call.reject("File not found: " + path);
            return;
        }

        try {
            Context context = getContext();
            Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
            String resolvedMime = mimeType.isEmpty() ? guessMimeType(file.getName()) : mimeType;
            if (resolvedMime == null || resolvedMime.isEmpty()) resolvedMime = "*/*";

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, resolvedMime);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);

            call.resolve(new JSObject().put("opened", true).put("path", file.getAbsolutePath()).put("mimeType", resolvedMime));
        } catch (Exception e) {
            call.reject("Open failed: " + e.getMessage());
        }
    }

    @PluginMethod
    public void listFiles(PluginCall call) {
        String rootPath = call.getString("path", "");
        if (rootPath.isEmpty()) {
            call.reject("No path provided");
            return;
        }

        File root = new File(rootPath);
        if (!root.exists()) {
            call.reject("Path not found: " + rootPath);
            return;
        }

        JSObject result = new JSObject();
        result.put("path", root.getAbsolutePath());
        result.put("name", root.getName());
        result.put("directory", root.isDirectory());
        result.put("size", root.isFile() ? root.length() : 0);
        result.put("mimeType", root.isFile() ? guessMimeType(root.getName()) : "inode/directory");

        if (root.isDirectory()) {
            File[] children = root.listFiles();
            List<JSObject> items = new ArrayList<>();
            if (children != null) {
                Arrays.sort(children, (a, b) -> a.getName().compareToIgnoreCase(b.getName()));
                for (File child : children) {
                    JSObject item = new JSObject();
                    item.put("name", child.getName());
                    item.put("path", child.getAbsolutePath());
                    item.put("directory", child.isDirectory());
                    item.put("size", child.isFile() ? child.length() : 0);
                    item.put("mimeType", child.isFile() ? guessMimeType(child.getName()) : "inode/directory");
                    items.add(item);
                }
            }
            result.put("items", items);
        }

        call.resolve(result);
    }

    @PluginMethod
    public void openContainingFolder(PluginCall call) {
        String path = call.getString("path", "");
        if (path.isEmpty()) {
            call.reject("No path provided");
            return;
        }

        File file = new File(path);
        File target = file.isDirectory() ? file : file.getParentFile();
        if (target == null || !target.exists()) {
            call.reject("Containing folder not found");
            return;
        }

        call.resolve(new JSObject().put("opened", true).put("path", target.getAbsolutePath()));
    }

    @PluginMethod
    public void getRoots(PluginCall call) {
        JSObject result = new JSObject();
        List<JSObject> roots = new ArrayList<>();

        roots.add(rootItem("App Files", getContext().getFilesDir()));
        File ext = getContext().getExternalFilesDir(null);
        if (ext != null) roots.add(rootItem("External Files", ext));
        File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        if (downloads != null) roots.add(rootItem("Downloads", downloads));
        File dcim = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
        if (dcim != null) roots.add(rootItem("Camera", dcim));
        File sdcard = Environment.getExternalStorageDirectory();
        if (sdcard != null) roots.add(rootItem("Storage Root", sdcard));

        result.put("roots", roots);
        call.resolve(result);
    }

    private JSObject rootItem(String label, File file) {
        JSObject item = new JSObject();
        item.put("name", label);
        item.put("path", file.getAbsolutePath());
        item.put("directory", true);
        item.put("size", 0);
        item.put("mimeType", "inode/directory");
        return item;
    }

    private String guessMimeType(String name) {
        String lower = name.toLowerCase();
        if (lower.endsWith(".apk")) return "application/vnd.android.package-archive";
        if (lower.endsWith(".apks")) return "application/vnd.android.package-archive";
        if (lower.endsWith(".zip")) return "application/zip";
        if (lower.endsWith(".json")) return "application/json";
        if (lower.endsWith(".html") || lower.endsWith(".htm")) return "text/html";
        if (lower.endsWith(".md") || lower.endsWith(".txt") || lower.endsWith(".log")) return "text/plain";
        String ext = MimeTypeMap.getFileExtensionFromUrl(name);
        if (ext == null || ext.isEmpty()) return "*/*";
        String guess = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.toLowerCase());
        return guess != null ? guess : "*/*";
    }
}
