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, useNodes } 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"),
});

const sourceSchema = z.object({
  id: z.string().min(1, "required"),
  branch: z.string(),
  rootDir: z.string(),
});

export function NodeAppDetails({ id, data }: ServiceNode) {
  const store = useStateStore();
  const nodes = useNodes();
  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)) {
          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]);

  const sourceForm = useForm<z.infer<typeof sourceSchema>>({
    resolver: zodResolver(sourceSchema),
    mode: "onChange",
    defaultValues: {
      id: data?.repository?.id,
      branch: data.repository && "branch" in data.repository ? data.repository.branch : undefined,
      rootDir: data.repository && "rootDir" in data.repository ? data.repository.rootDir : undefined,
    },
  });
  useEffect(() => {
    const sub = sourceForm.watch((value: DeepPartial<z.infer<typeof sourceSchema>>, { name }: { name?: keyof z.infer<typeof sourceSchema> | undefined, type?: EventType | undefined }) => {
      console.log(value);
      if (name === "id") {
        let edges = store.edges;
        if (data?.repository?.id !== undefined) {
          edges = edges.filter((e) => {
            if (e.target === id && e.targetHandle === "repository" && e.source === data.repository.id) {
              return false;
            } else {
              return true;
            }
          });
        }
        if (value.id !== undefined) {
          edges = edges.concat({
            id: uuidv4(),
            source: value.id,
            sourceHandle: "repository",
            target: id,
            targetHandle: "repository",
          });
        }
        store.setEdges(edges);
        store.updateNodeData<"app">(id, {
          repository: {
            id: value.id,
          },
        });
      } else if (name === "branch") {
        store.updateNodeData<"app">(id, {
          repository: {
            ...data?.repository,
            branch: value.branch,
          },
        });
      } else if (name === "rootDir") {
        store.updateNodeData<"app">(id, {
          repository: {
            ...data?.repository,
            rootDir: value.rootDir,
          },
        });
      }
    });
    return () => sub.unsubscribe();
  }, [id, data, sourceForm, 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>
      Source
      <Form {...sourceForm}>
        <form className="space-y-2">
          <FormField
            control={sourceForm.control}
            name="id"
            render={({ field }) => (
              <FormItem>
                <Select onValueChange={field.onChange} defaultValue={field.value}>
                  <FormControl>
                    <SelectTrigger>
                      <SelectValue placeholder="Repository" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent>
                    {nodes.filter((n) => n.type === "github" && n.data.repository?.id !== undefined).map((n) => (
                      <SelectItem key={n.id} value={n.id}>{`${n.data.repository?.sshURL}`}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={sourceForm.control}
            name="branch"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="master" className="border border-black" {...field} />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={sourceForm.control}
            name="rootDir"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input placeholder="/" className="border border-black" {...field} />
                </FormControl>
                <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} />
    </>);
}