import { v4 as uuidv4 } from "uuid";
import { useStateStore, AppNode, nodeLabel, useEnv, GatewayTCPNode, nodeIsConnectable } from '@/lib/state';
import { Edge, Handle, Position, useNodes } from '@xyflow/react';
import { NodeRect } from './node-rect';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, EventType, DeepPartial } from 'react-hook-form';
import { Form, FormControl, FormField, FormItem, FormMessage } from './ui/form';
import { Input } from './ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
import { Button } from "./ui/button";

const schema = z.object({
  network: z.string().min(1, "reqired"),
  subdomain: z.string().min(1, "required"),
});

const connectedToSchema = z.object({
  serviceId: z.string(),
  portId: z.string(),
});

export function NodeGatewayTCP(node: GatewayTCPNode) {
  const { id, selected } = node;
  const isConnectableNetwork = useMemo(() => nodeIsConnectable(node, "subdomain"), [node]);
  const isConnectable = useMemo(() => nodeIsConnectable(node, "tcp"), [node]);
  return (
    <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
      {nodeLabel(node)}
      <Handle
        type={"source"}
        id="subdomain"
        position={Position.Top}
        isConnectable={isConnectableNetwork}
        isConnectableStart={isConnectableNetwork}
        isConnectableEnd={isConnectableNetwork}
      />
      <Handle
        type={"target"}
        id="tcp"
        position={Position.Bottom}
        isConnectable={isConnectable}
        isConnectableStart={isConnectable}
        isConnectableEnd={isConnectable}
      />
    </NodeRect>
  );
}

export function NodeGatewayTCPDetails({ id, data }: GatewayTCPNode) {
  const store = useStateStore();
  const env = useEnv();
  const form = useForm<z.infer<typeof schema>>({
    resolver: zodResolver(schema),
    mode: "onChange",
    defaultValues: {
      network: data.network,
      subdomain: data.subdomain,
    },
  });
  useEffect(() => {
    const sub = form.watch((value: DeepPartial<z.infer<typeof schema>>, { name }: { name?: keyof z.infer<typeof schema> | undefined, type?: EventType | undefined }) => {
      if (name === "network") {
        let edges = store.edges;
        if (data.network !== undefined) {
          edges = edges.filter((e) => {
            console.log(e);
            if (e.source === id && e.sourceHandle === "subdomain" && e.target === data.network && e.targetHandle === "subdomain") {
              return false;
            } else {
              return true;
            }
          });
        }
        if (value.network !== undefined) {
          edges = edges.concat({
            id: uuidv4(),
            source: id,
            sourceHandle: "subdomain",
            target: value.network,
            targetHandle: "subdomain",
          });
        }
        store.setEdges(edges);
        store.updateNodeData<"gateway-tcp">(id, { network: value.network });
      } else if (name === "subdomain") {
        store.updateNodeData<"gateway-tcp">(id, { subdomain: value.subdomain });
      }
    });
    return () => sub.unsubscribe();
  }, [id, data, form, store]);
  const connectedToForm = useForm<z.infer<typeof connectedToSchema>>({
    resolver: zodResolver(connectedToSchema),
    mode: "onSubmit",
    defaultValues: {
      serviceId: data.selected?.serviceId,
      portId: data.selected?.portId,
    },
  });
  useEffect(() => {
    connectedToForm.reset({
      serviceId: data.selected?.serviceId,
      portId: data.selected?.portId,
    });
    console.log(connectedToForm.getValues());
  }, [connectedToForm, data]);
  const nodes = useNodes<AppNode>();
  const [selected, setSelected] = useState<AppNode | undefined>(undefined);
  useEffect(() => {
    if (data.selected?.serviceId == null) {
      setSelected(undefined);
    } else {
      const serviceId = data.selected.serviceId;
      setSelected(nodes.find((n) => n.id === serviceId));
    }
  }, [data, setSelected]);
  const selectable = useMemo(() => {
    console.log(selected);
    return nodes.filter((n) => {
      if (n.id === id) {
        return false;
      }
      if (selected != null && selected.id === id) {
        return true;
      }
      if ("ports" in n.data && (n.data.ports || []).length > 0) {
        return true;
      }
      return false;
    })
  }, [nodes, selected]);
  useEffect(() => {
    const sub = connectedToForm.watch((value: DeepPartial<z.infer<typeof connectedToSchema>>, { name, type }: { name?: keyof z.infer<typeof connectedToSchema> | undefined, type?: EventType | undefined }) => {
      if (type !== "change") {
        return;
      }
      switch (name) {
        case "serviceId":
          if (!value.serviceId) {
            break;
          }
          store.updateNodeData<"gateway-tcp">(id, {
            selected: {
              serviceId: value.serviceId,
            },
          });
          break;
        case "portId":
          if (!value.portId) {
            break;
          }
          store.updateNodeData<"gateway-tcp">(id, {
            selected: {
              serviceId: value.serviceId,
              portId: value.portId,
            },
          });
          break;
      }
    });
    return () => sub.unsubscribe();
  }, [connectedToForm, store]);
  const [nodeLabels, setNodeLabels] = useState(new Map<string, string>());
  const [portLabels, setPortLabels] = useState(new Map<string, string>());
  useEffect(() => {
    setNodeLabels(new Map((data.exposed || []).map((e) => [e.serviceId, nodeLabel(nodes.find((n) => n.id === e.serviceId)!)])));
    setPortLabels(new Map((data.exposed || []).map((e) => [`${e.serviceId} - ${e.portId}`, (nodes.find((n) => n.id === e.serviceId)!.data.ports || []).find((p) => p.id === e.portId)!.name])));
  }, [nodes, data, setNodeLabels, setPortLabels]);
  const onSubmit = useCallback((values: z.infer<typeof connectedToSchema>) => {
    const edges = store.edges.filter((e) => e.target !== id);
    const exp = (data.exposed || []).concat({
      serviceId: values.serviceId,
      portId: values.portId,
    });
    store.updateNodeData<"gateway-tcp">(id, {
      exposed: exp,
      selected: undefined,
    });
    store.setEdges(edges.concat(exp.map((e): Edge => ({
      id: uuidv4(),
      source: e.serviceId,
      sourceHandle: "ports",
      target: id,
      targetHandle: "tcp",
    }))));
  }, [id, data, connectedToForm, store, setNodeLabels, setPortLabels]);
  return (
    <>
      <Form {...form}>
        <form className="space-y-2">
          <FormField
            control={form.control}
            name="network"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Network" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {env.networks.map((n) => (
                      <SelectItem key={n.name} value={n.domain}>{`${n.name} - ${n.domain}`}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="subdomain"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="subdomain" className="border border-black" {...field} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
        </form>
      </Form>
      Exposed Services
      <ul>
        {(data.exposed || []).map((e, i) => (
          <li key={i}>
            {nodeLabels.get(e.serviceId)} - {portLabels.get(`${e.serviceId} - ${e.portId}`)}
          </li>
        ))}
      </ul>
      <Form {...connectedToForm}>
        <form className="space-y-2" onSubmit={connectedToForm.handleSubmit(onSubmit)}>
          <FormField
            control={connectedToForm.control}
            name="serviceId"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Service" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {selectable.map((n) => (
                      <SelectItem value={n.id}>{nodeLabel(n)}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={connectedToForm.control}
            name="portId"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Port" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {selected && (selected.data.ports || []).map((p) => (
                      <SelectItem key={p.id} value={p.id}>{p.name} - {p.value}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit">Expose</Button>
        </form>
      </Form>
    </>
  );
}