import { v4 as uuidv4 } from "uuid";
import { useStateStore, AppNode, GatewayHttpsNode, ServiceNode, nodeLabel, useEnv, nodeIsConnectable } from '@/lib/state';
import { Handle, Position, useNodes } from '@xyflow/react';
import { NodeRect } from './node-rect';
import { useEffect, useMemo } 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';

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

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

export function NodeGatewayHttps(node: GatewayHttpsNode) {
  const { id, selected } = node;
  const isConnectableNetwork = useMemo(() => nodeIsConnectable(node, "subdomain"), [node]);
  const isConnectable = useMemo(() => nodeIsConnectable(node, "https"), [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="https" 
        position={Position.Bottom}
        isConnectable={isConnectable}
        isConnectableStart={isConnectable} 
        isConnectableEnd={isConnectable} 
      />
    </NodeRect>
  );
}

export function NodeGatewayHttpsDetails({ id, data }: GatewayHttpsNode) {
  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-https">(id, { network: value.network });
      } else if (name === "subdomain") {
        store.updateNodeData<"gateway-https">(id, { subdomain: value.subdomain });
      }
    });
    return () => sub.unsubscribe();
  }, [id, data, form, store]);
  const connectedToForm = useForm<z.infer<typeof connectedToSchema>>({
    resolver: zodResolver(connectedToSchema),
    mode: "onChange",
    defaultValues: {
      id: data.https?.serviceId,
      portId: data.https?.portId,
    },
  });
  useEffect(() => {
    connectedToForm.reset({
      id: data.https?.serviceId,
      portId: data.https?.portId,
    });
  }, [connectedToForm, data]);
  const nodes = useNodes<AppNode>();
  const selected = useMemo(() => {
    if (data !== undefined && data.https !== undefined) {
      const https = data.https;
      return nodes.find((n) => n.id === https.serviceId)! as ServiceNode;
    }
    return null;
  }, [data]);
  const selectable = useMemo(() => {
    return nodes.filter((n) => {
      if (n.id === id) {
        return false;
      }
      if (selected !== null && selected.id === id) {
        return true;
      }
      if (n.type !== "app") {
        return false;
      }
      return n.data && n.data.ports && n.data.ports.length > 0;
    })
  }, [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 }) => {
      console.log({ name, type });
      if (type !== "change") {
        return;
      }
      switch (name) {
        case "id":
          if (!value.id) {
            break;
          }
          const current = store.edges.filter((e) => e.target === id);
          const cid = current[0] ? current[0].id : undefined;
          store.replaceEdge({
            source: value.id,
            sourceHandle: "ports",
            target: id,
            targetHandle: "https",
          }, cid);
          break;
        case "portId":
          store.updateNodeData<"gateway-https">(id, {
            https: {
              serviceId: value.id,
              portId: value.portId,
            }
          });
          break;
      }
    });
    return () => sub.unsubscribe();
  }, [connectedToForm, store, selectable]);
  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>
      <Form {...connectedToForm}>
        <form className="space-y-2">
        <FormField
            control={connectedToForm.control}
            name="id"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Service" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {selectable.map((n) => (
                      <SelectItem key={n.id} 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>           
            )}
          />
        </form>
      </Form>
    </>
  );
}