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 isConnectable = useMemo(() => nodeIsConnectable(node, "https"), [node]);
  return (
    <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
      {nodeLabel(node)}
      <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") {
        if (value.network !== undefined) {
          store.updateNodeData<"gateway-https">(id, { network: value.network });
        } else {
          
        }
      } else if (name === "subdomain") {
        store.updateNodeData<"gateway-https">(id, { subdomain: value.subdomain });
      }
    });
    return () => sub.unsubscribe();
  }, [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>
    </>
  );
}