import { AppContext } from "@/src/pages/_app";
import {
    NormalizedServerObject,
    ParsedDeploymentServiceConfig,
} from "@/src/types";
import ArrowedLink from "@/twui/components/layout/ArrowedLink";
import Button from "@/twui/components/layout/Button";
import H2 from "@/twui/components/layout/H2";
import Row from "@/twui/components/layout/Row";
import Stack from "@/twui/components/layout/Stack";
import { useContext, useEffect, useRef, useState } from "react";
import ServiceClusterServer from "../service/(partials)/cluster-server";
import { twMerge } from "tailwind-merge";
import Select from "@/twui/components/form/Select";
import useStatus from "@/twui/components/hooks/useStatus";
import Loading from "@/twui/components/elements/Loading";
import _ from "lodash";

type Props = {
    service: ParsedDeploymentServiceConfig;
};

export default function DeploymentService({ service }: Props) {
    const { pageProps, ws } = useContext(AppContext);
    const { deployment } = pageProps;

    const { ready, setReady } = useStatus();

    const children_services = deployment?.services.filter(
        (srv) => srv.parent_service_name == service.service_name,
    );

    const all_clusters = [service, ...(children_services || [])];

    const [targetCluster, setTargetCluster] = useState<
        ParsedDeploymentServiceConfig | undefined
    >(all_clusters?.[0]);

    const targetClusterIndex =
        all_clusters.findIndex(
            (cl) => cl.service_name == targetCluster?.service_name,
        ) + 1;

    const cluster_servers = targetCluster?.servers;

    const [targetServer, setTargetServer] = useState<
        NormalizedServerObject | undefined
    >(cluster_servers?.[0]);

    const portRef = useRef<number>(undefined);

    function killPort(port: number) {
        ws.sendData({
            event: "client:kill-port",
            server: targetServer,
            service: _.omit(service, ["servers"]),
            port,
        });
    }

    useEffect(() => {
        setTargetServer(targetCluster?.servers?.[0]);
    }, [targetCluster]);

    useEffect(() => {
        setReady(false);

        if (targetServer && portRef.current) {
            killPort(portRef.current);
        }

        setTimeout(() => {
            setReady(true);
        }, 2000);
    }, [targetServer]);

    return (
        <Stack className="grid-cell">
            <Stack className="grid-cell-content">
                <Row className="w-full justify-between">
                    <H2>{service.service_name}</H2>
                    <ArrowedLink
                        link={{
                            url: `/admin/services/${service.service_name}`,
                            title: `View`,
                        }}
                    />
                </Row>

                <code>{service.service_name} service</code>
            </Stack>

            <hr />
            <Stack className="gap-0">
                <Row className="p-4 grid md:grid-cols-2">
                    <Select
                        options={all_clusters.map((cl, index) => ({
                            value: cl.service_name,
                            title: `Cluster #${index + 1}`,
                        }))}
                        changeHandler={(v) => {
                            setTargetCluster(
                                all_clusters.find((cl) => cl.service_name == v),
                            );
                        }}
                    />
                    {cluster_servers ? (
                        <Select
                            options={cluster_servers.map((srv) => ({
                                value: srv.private_ip!,
                                title: srv.private_ip,
                            }))}
                            changeHandler={(v) => {
                                setTargetServer(
                                    cluster_servers.find(
                                        (srv) => srv.private_ip == v,
                                    ),
                                );
                            }}
                        />
                    ) : undefined}
                </Row>

                {ready ? (
                    targetServer ? (
                        <ServiceClusterServer
                            server={targetServer}
                            service={service}
                            portRef={portRef}
                        />
                    ) : undefined
                ) : undefined}
            </Stack>
        </Stack>
    );
}
