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";
import { Textarea } from "./ui/textarea";

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]);
  const setPreBuildCommands = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
    store.updateNodeData<"app">(id, {
      preBuildCommands: e.currentTarget.value,
    });
  }, [id, 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>
      Pre-Build Commands
      <Textarea placeholder="new line separated list of commands to run before running the service" value={data.preBuildCommands} onChange={setPreBuildCommands} />
    </>);
}