import { v4 as uuidv4 } from "uuid";
import { NodeRect } from './node-rect';
import { useStateStore, ServiceNode, ServiceTypes, nodeLabel, BoundEnvVar, AppState, nodeIsConnectable, GatewayTCPNode, GatewayHttpsNode } from '@/lib/state';
import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { z } from "zod";
import { DeepPartial, EventType, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Form, FormControl, FormField, FormItem, FormMessage } from './ui/form';
import { Input } from './ui/input';
import { Button } from './ui/button';
import { Handle, Position } from "@xyflow/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { PencilIcon, XIcon } from "lucide-react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";

export function NodeApp(node: ServiceNode) {
  const { id, selected } = node;
  const isConnectablePorts = useMemo(() => nodeIsConnectable(node, "ports"), [node]);
  const isConnectableRepository = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
  return (
    <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
      <div style={{ padding: '10px 20px' }}>
        {nodeLabel(node)}
        <Handle
          id="repository"
          type={"target"}
          position={Position.Left}
          isConnectableStart={isConnectableRepository}
          isConnectableEnd={isConnectableRepository}
          isConnectable={isConnectableRepository}
        />
        <Handle
          id="ports"
          type={"source"}
          position={Position.Top}
          isConnectableStart={isConnectablePorts}
          isConnectableEnd={isConnectablePorts}
          isConnectable={isConnectablePorts}
        />
        <Handle
          id="env_var"
          type={"target"}
          position={Position.Bottom}
          isConnectableStart={true}
          isConnectableEnd={true}
          isConnectable={true}
        />
      </div>
    </NodeRect>
  );
}

const schema = z.object({
  name: z.string().min(1, "requried"),
  type: z.enum(ServiceTypes),
});

const portSchema = z.object({
  name: z.string().min(1, "required"),
  value: z.coerce.number().gt(0, "can not be negative"),
});

export function NodeAppDetails({ id, data }: ServiceNode) {
  const store = useStateStore();
  const form = useForm<z.infer<typeof schema>>({
    resolver: zodResolver(schema),
    mode: "onChange",
    defaultValues: {
      name: data.label,
      type: data.type,
    }
  });
  const portForm = useForm<z.infer<typeof portSchema>>({
    resolver: zodResolver(portSchema),
    mode: "onSubmit",
    defaultValues: {
      name: "",
      value: 0,
    }
  });
  const onSubmit = useCallback((values: z.infer<typeof portSchema>) => {
    const portId = uuidv4();
    store.updateNodeData<"app">(id, {
      ports: (data.ports || []).concat({
        id: portId,
        name: values.name,
        value: values.value,
      }),
      envVars: (data.envVars || []).concat({
        id: uuidv4(),
        source: null,
        portId,
        name: `DODO_PORT_${values.name.toUpperCase()}`,
      }),
    });
    portForm.reset();
  }, [data, portForm]);
  useEffect(() => {
    const sub = form.watch((value: DeepPartial<z.infer<typeof schema>>, { name, type }: { name?: keyof z.infer<typeof schema> | undefined, type?: EventType | undefined }) => {
      console.log({ name, type });
      if (type !== "change") {
        return;
      }
      switch (name) {
        case "name":
          if (!value.name) {
            break;
          }
          store.updateNodeData<"app">(id, {
            label: value.name,
          });
          break;
        case "type":
          if (!value.type) {
            break;
          }
          store.updateNodeData<"app">(id, {
            type: value.type,
          })
          break;
      }
    });
    return () => sub.unsubscribe();
  }, [form, store]);
  const focus = useCallback((field: any, name: string) => {
    return (e: HTMLElement | null) => {
      field.ref(e);
      if (e != null && name === data.activeField) {
        console.log(e);
        e.focus();
        store.updateNodeData(id, {
          activeField: undefined,
        });
      }
    }
  }, [data, store]);
  const [typeProps, setTypeProps] = useState({});
  useEffect(() => {
    if (data.activeField === "type") {
      setTypeProps({
        open: true,
        onOpenChange: () => store.updateNodeData(id, { activeField: undefined }),
      });
    } else {
      setTypeProps({});
    }
  }, [store, data, setTypeProps]);
  const editAlias = useCallback((e: BoundEnvVar) => {
    return () => {
      store.updateNodeData(id, {
        ...data,
        envVars: data.envVars!.map((o) => {
          if (o.id !== e.id) {
            return o;
          } else return {
            ...o,
            isEditting: true,
          }
        }),
      });
    };
  }, [id, data, store]);
  const saveAlias = (e: BoundEnvVar, value: string, store: AppState) => {
    store.updateNodeData(id, {
      ...data,
      envVars: data.envVars!.map((o) => {
        if (o.id !== e.id) {
          return o;
        }
        if (value) {
          return {
            ...o,
            isEditting: false,
            alias: value.toUpperCase(),
          }
        }
        console.log(o);
        if ("alias" in o) {
          const { alias: tmp, ...rest } = o;
          console.log(rest);
          return {
            ...rest,
            isEditting: false,
          };
        }
        return {
          ...o,
          isEditting: false,
        };
      }),
    });
  };
  const saveAliasOnEnter = useCallback((e: BoundEnvVar) => {
    return (event: KeyboardEvent<HTMLInputElement>) => {
      if (event.key === "Enter") {
        event.preventDefault();
        saveAlias(e, event.currentTarget.value, store);
      }
    }
  }, [id, data, store]);
  const saveAliasOnBlur = useCallback((e: BoundEnvVar) => {
    return (event: FocusEvent<HTMLInputElement>) => {
      saveAlias(e, event.currentTarget.value, store);
    }
  }, [id, data, store]);
  const removePort = useCallback((portId: string) => {
    // TODO(gio): this is ugly
    const tcpRemoved = new Set<string>();
    console.log(store.edges);
    store.setEdges(store.edges.filter((e) => {
      if (e.source !== id || e.sourceHandle !== "ports") {
        return true;
      }
      const tn = store.nodes.find((n) => n.id == e.target)!;
      if (e.targetHandle === "https") {
        const t = tn as GatewayHttpsNode;
        if (t.data.https?.serviceId === id && t.data.https.portId === portId) {
          return false;
        }
      }
      if (e.targetHandle === "tcp") {
        const t = tn as GatewayTCPNode;
        if (tcpRemoved.has(t.id)) {
          return true;
        }
        if (t.data.exposed.find((e) => e.serviceId === id && e.portId === portId)) {
          console.log(11111, e);
          tcpRemoved.add(t.id);
          return false;
        }
      }
      if (e.targetHandle === "env_var") {
        if (tn && (tn.data.envVars || []).find((ev) => ev.source === id && "portId" in ev && ev.portId === portId)) {
          return false;
        }
      }
      return true;
    }));
    store.nodes.filter((n) => n.type === "gateway-https" && n.data.https && n.data.https.serviceId === id && n.data.https.portId === portId).forEach((n) => {
      store.updateNodeData<"gateway-https">(n.id, {
        https: undefined,
      });
    });
    store.nodes.filter((n) => n.type === "gateway-tcp").forEach((n) => {
      const filtered = n.data.exposed.filter((e) => {
        if (e.serviceId === id && e.portId === portId) {
          return false;
        } else {
          return true;
        }
      })
      if (filtered.length != n.data.exposed.length) {
        store.updateNodeData<"gateway-tcp">(n.id, {
          exposed: filtered,
        });
      }
    });
    store.nodes.filter((n) => n.type === "app" && n.data.envVars).forEach((n) => {
      store.updateNodeData<"app">(n.id, {
        envVars: n.data.envVars.filter((ev) => {
          if (ev.source === id && "portId" in ev && ev.portId === portId) {
            return false;
          }
          return true;
        })
      });
    });
    store.updateNodeData<"app">(id, {
      ports: (data.ports || []).filter((p) => p.id !== portId),
      envVars: (data.envVars || []).filter((ev) => !(ev.source === null && "portId" in ev && ev.portId === portId)),
    });
  }, [id, data, store]);
  return (
    <>
      <Form {...form}>
        <form>
          <FormField
            control={form.control}
            name="name"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="name" className="border border-black" {...field} ref={focus(field, "name")} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="type"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value} {...typeProps}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Runtime" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {ServiceTypes.map((t) => (
                      <SelectItem key={t} value={t}>{t}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
        </form>
      </Form>
      Ports
      <ul>
        {data && data.ports && data.ports.map((p) => (<li key={p.id}><Button size={"icon"} variant={"ghost"} onClick={() => removePort(p.id)}><XIcon /></Button> {p.name} - {p.value}</li>))}
      </ul>
      <Form {...portForm}>
        <form className="flex flex-row space-x-1" onSubmit={portForm.handleSubmit(onSubmit)}>
          <FormField
            control={portForm.control}
            name="name"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="name" className="border border-black" {...field} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={portForm.control}
            name="value"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="value" className="border border-black" {...field} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit">Add Port</Button>
        </form>
      </Form>
      Env Vars
      <ul>
        {data && data.envVars && data.envVars.map((v) => {
          if ("name" in v) {
            const value = "alias" in v ? v.alias : v.name;
            if (v.isEditting) {
              return (<li key={v.id}><Input type="text" className="border border-black" defaultValue={value} onKeyUp={saveAliasOnEnter(v)} onBlur={saveAliasOnBlur(v)} autoFocus={true} /></li>);
            }
            return (
              <li key={v.id} onClick={editAlias(v)}>
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger>
                      <Button size={"icon"} variant={"ghost"}><PencilIcon /></Button>
                      {value}
                    </TooltipTrigger>
                    <TooltipContent>
                      {v.name}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
              </li>
            );
          }
        })}
      </ul>
    </>);
}