import React from 'react';
import { Box, Text, render } from 'ink';
import chalk from 'chalk';
import axios from 'axios';
import fs from 'fs';
import path from 'path';
import os from 'os';
// React component for Current Bundle IDs table
function CurrentBundleTable({ manifest }) {
    return (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
        React.createElement(Text, { color: "blue" }, "Current Bundle IDs:"),
        React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray" },
            React.createElement(Box, null,
                React.createElement(Text, null, "Bundle Type         "),
                React.createElement(Text, null, "\u2502 ID           ")),
            React.createElement(Box, null,
                React.createElement(Text, null, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
                React.createElement(Text, null, "\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),
            React.createElement(Box, null,
                React.createElement(Text, null, "iOS Bundle ID       "),
                React.createElement(Text, null,
                    "\u2502 ",
                    (manifest.iosBundleId || 'null').toString().padEnd(12),
                    " ")),
            React.createElement(Box, null,
                React.createElement(Text, null, "Android Bundle ID   "),
                React.createElement(Text, null,
                    "\u2502 ",
                    (manifest.androidBundleId || 'null').toString().padEnd(12),
                    " ")),
            React.createElement(Box, null,
                React.createElement(Text, null, "Plugins Bundle ID   "),
                React.createElement(Text, null,
                    "\u2502 ",
                    (manifest.pluginsBundleId || 'null').toString().padEnd(12),
                    " ")),
            React.createElement(Box, null,
                React.createElement(Text, null, "Navigators Bundle ID"),
                React.createElement(Text, null,
                    "\u2502 ",
                    (manifest.navigatorsBundleId || 'null').toString().padEnd(12),
                    " ")))));
}
// React component for Available Bundles table
function AvailableBundlesTable({ bundleType, bundles }) {
    return (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
        React.createElement(Text, { color: "blue" },
            "Available ",
            bundleType,
            " bundles:"),
        React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray" },
            React.createElement(Box, null,
                React.createElement(Text, null, "ID       "),
                React.createElement(Text, null, "\u2502 Type                ")),
            React.createElement(Box, null,
                React.createElement(Text, null, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
                React.createElement(Text, null, "\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),
            bundles.map((bundle, index) => {
                const id = bundle.id !== null ? bundle.id.toString() : 'null';
                return (React.createElement(Box, { key: index },
                    React.createElement(Text, null,
                        id.padEnd(8),
                        " "),
                    React.createElement(Text, null,
                        "\u2502 ",
                        bundle.type.padEnd(19),
                        " ")));
            }))));
}
function serializeAxiosError(err) {
    if (err && err.response && err.code) {
        let errorBody = err.response.data;
        if (typeof errorBody === "object") {
            errorBody = JSON.stringify(err.response.data);
        }
        let serialized = `calling: ${err.request.protocol}//${err.request.host}${err.request.path}
${chalk.red(err.code)}
${chalk.yellow(err.response.status)} ${chalk.yellow(err.response.statusText)}`;
        if (errorBody) {
            serialized += `\n\n${errorBody}`;
        }
        return serialized;
    }
    else {
        return null;
    }
}
async function getUser() {
    try {
        const homeDir = os.homedir();
        const apptileCliDir = path.join(homeDir, '.apptile-cli');
        const stateFilePath = path.join(apptileCliDir, 'apptile-cli-state.mjson');
        const rawdata = fs.readFileSync(stateFilePath, { encoding: "utf8" });
        const parsed = JSON.parse(rawdata);
        const { status, data } = await axios.get("https://api.apptile.io/api/users/me", {
            headers: {
                cookie: parsed.cookie
            }
        });
        if (status === 200) {
            return { user: data, cookie: parsed.cookie };
        }
        else {
            return { user: null, cookie: "" };
        }
    }
    catch (err) {
        const msg = serializeAxiosError(err);
        if (msg) {
            console.log(msg);
        }
        else {
            console.log(err);
        }
        return { user: null, cookie: "" };
    }
}
async function getManifest(appId) {
    try {
        const { data } = await axios.get(`https://api.apptile.io/api/v2/app/${appId}/manifest`);
        return data;
    }
    catch (err) {
        const msg = serializeAxiosError(err);
        if (msg) {
            console.log(msg);
        }
        return null;
    }
}
// Main React component for CodePush functionality
function CodePushApp({ options }) {
    const [config, setConfig] = React.useState(null);
    const [manifest, setManifest] = React.useState(null);
    const [bundles, setBundles] = React.useState([]);
    const [error, setError] = React.useState('');
    const [loading, setLoading] = React.useState(true);
    React.useEffect(() => {
        async function loadData() {
            try {
                // Check if apptile.config.mjson exists in current directory
                const configPath = path.resolve(process.cwd(), "apptile.config.mjson");
                if (!fs.existsSync(configPath)) {
                    setError("Error: apptile.config.mjson not found in current directory.\nPlease run this command from the root of your apptile project.");
                    setLoading(false);
                    return;
                }
                // Read apptile.config.mjson
                let configData;
                try {
                    const configRaw = fs.readFileSync(configPath, { encoding: "utf8" });
                    configData = JSON.parse(configRaw);
                }
                catch (err) {
                    setError(`Error: Could not read or parse apptile.config.mjson\n${err.message}`);
                    setLoading(false);
                    return;
                }
                if (!configData.APP_ID) {
                    setError("Error: APP_ID not found in apptile.config.mjson");
                    setLoading(false);
                    return;
                }
                if (!configData.APPTILE_BACKEND_URL) {
                    setError("Error: APPTILE_BACKEND_URL not found in apptile.config.mjson");
                    setLoading(false);
                    return;
                }
                setConfig(configData);
                // If showing current bundle IDs, fetch the manifest
                if (options.showCurrent) {
                    try {
                        const manifestData = await getManifest(configData.APP_ID);
                        if (!manifestData) {
                            setError("Error: Could not fetch app manifest");
                            setLoading(false);
                            return;
                        }
                        setManifest(manifestData);
                    }
                    catch (err) {
                        setError(`Error fetching manifest: ${err.message}`);
                        setLoading(false);
                        return;
                    }
                }
                // If listing available bundles, fetch them
                if (options.listAvailableBundles) {
                    const bundleType = options.listAvailableBundles.toLowerCase();
                    const validTypes = ['plugins', 'ios', 'navigators', 'android'];
                    if (!validTypes.includes(bundleType)) {
                        setError(`Error: Invalid bundle type '${bundleType}'. Valid types are: ${validTypes.join(', ')}`);
                        setLoading(false);
                        return;
                    }
                    try {
                        // Get user authentication
                        const { cookie } = await getUser();
                        if (!cookie) {
                            setError("Not logged in! Please run 'aptl login' first.");
                            setLoading(false);
                            return;
                        }
                        // Call the API to get bundles
                        const apiUrl = `${configData.APPTILE_BACKEND_URL}/api/v2/app/${configData.APP_ID}/bundles`;
                        const { data } = await axios.get(apiUrl, {
                            headers: {
                                cookie: cookie
                            }
                        });
                        // Filter bundles by type
                        const typeMapping = {
                            'ios': 'ios-jsbundle',
                            'android': 'android-jsbundle',
                            'plugins': 'plugins',
                            'navigators': 'navigators'
                        };
                        const apiType = typeMapping[bundleType];
                        const filteredBundles = data.filter((bundle) => bundle.type === apiType);
                        setBundles(filteredBundles);
                    }
                    catch (err) {
                        const msg = serializeAxiosError(err);
                        if (msg) {
                            setError(msg);
                        }
                        else {
                            setError(`Error fetching bundles: ${err.message}`);
                        }
                        setLoading(false);
                        return;
                    }
                }
                setLoading(false);
            }
            catch (err) {
                setError(`Error: ${err.message}`);
                setLoading(false);
            }
        }
        loadData();
    }, [options]);
    if (loading) {
        return React.createElement(Text, null, "Loading...");
    }
    if (error) {
        return React.createElement(Text, { color: "red" }, error);
    }
    if (options.showCurrent && manifest) {
        return React.createElement(CurrentBundleTable, { manifest: manifest });
    }
    if (options.listAvailableBundles && config) {
        const bundleType = options.listAvailableBundles.toLowerCase();
        if (bundles.length === 0) {
            return React.createElement(Text, { color: "yellow" },
                "No ",
                bundleType,
                " bundles found.");
        }
        return React.createElement(AvailableBundlesTable, { bundleType: bundleType, bundles: bundles });
    }
    // If no options provided, show help
    return (React.createElement(Box, { flexDirection: "column" },
        React.createElement(Text, { color: "yellow" }, "Please specify an option:"),
        React.createElement(Text, null, "  --show-current                           Show current bundle IDs"),
        React.createElement(Text, null, "  --list-available-bundles <type>          List available bundles"),
        React.createElement(Text, null, "                                           Types: plugins, ios, navigators, android"),
        React.createElement(Text, null),
        React.createElement(Text, null, "Examples:"),
        React.createElement(Text, null, "  aptl codepush --show-current"),
        React.createElement(Text, null, "  aptl codepush --list-available-bundles=plugins")));
}
export async function codepushAction(options) {
    // Render the React component using Ink
    render(React.createElement(CodePushApp, { options: options }));
}
