import { FormEvent, useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { api } from "../../api/client";
import { Page } from "../../components/Page";
import { Table } from "../../components/Table";

const columns = [
  { key: "name", label: "Policy" },
  { key: "targets", label: "Targets" },
  { key: "destinations", label: "Destinations" },
  { key: "mode", label: "Mode" }
];

export function PoliciesPage() {
  const queryClient = useQueryClient();
  const query = useQuery({
    queryKey: ["policies"],
    queryFn: api.policies
  });
  const usersQuery = useQuery({
    queryKey: ["users"],
    queryFn: api.users
  });
  const [form, setForm] = useState({
    name: "",
    description: "",
    destinations: "",
    targetUserId: "",
    fullTunnel: false
  });

  const createMutation = useMutation({
    mutationFn: api.createPolicy,
    onSuccess: () => {
      setForm({ name: "", description: "", destinations: "", targetUserId: "", fullTunnel: false });
      void queryClient.invalidateQueries({ queryKey: ["policies"] });
    }
  });

  const rows = query.data?.map((policy) => ({
    name: policy.name,
    targets: "assigned targets",
    destinations: policy.destinations?.join(", ") ?? (policy.full_tunnel ? "0.0.0.0/0" : "-"),
    mode: policy.full_tunnel ? "Full tunnel" : "Split tunnel"
  })) ?? [];

  const selectableUsers = useMemo(() => usersQuery.data ?? [], [usersQuery.data]);

  function onSubmit(event: FormEvent) {
    event.preventDefault();
    if (!form.targetUserId) {
      return;
    }
    createMutation.mutate({
      name: form.name,
      description: form.description,
      priority: 100,
      effect: "allow",
      full_tunnel: form.fullTunnel,
      destinations: form.fullTunnel ? ["0.0.0.0/0"] : form.destinations.split(",").map((value) => value.trim()).filter(Boolean),
      targets: [{ type: "user", id: form.targetUserId }]
    });
  }

  return (
    <Page
      title="Policies"
      subtitle="Manage per-user and per-device access controls enforced at the gateway."
      actions={<span className="pill">Gateway enforced</span>}
    >
      <form className="inline-form" onSubmit={onSubmit}>
        <input placeholder="policy name" value={form.name} onChange={(event) => setForm((value) => ({ ...value, name: event.target.value }))} />
        <input placeholder="description" value={form.description} onChange={(event) => setForm((value) => ({ ...value, description: event.target.value }))} />
        <input
          placeholder="destinations: 172.16.10.0/24,10.0.0.5/32"
          value={form.destinations}
          onChange={(event) => setForm((value) => ({ ...value, destinations: event.target.value }))}
          disabled={form.fullTunnel}
        />
        <select value={form.targetUserId} onChange={(event) => setForm((value) => ({ ...value, targetUserId: event.target.value }))}>
          <option value="">target user</option>
          {selectableUsers.map((user) => (
            <option key={user.id} value={user.id}>
              {user.username}
            </option>
          ))}
        </select>
        <label className="checkbox">
          <input type="checkbox" checked={form.fullTunnel} onChange={(event) => setForm((value) => ({ ...value, fullTunnel: event.target.checked }))} />
          Full tunnel
        </label>
        <button className="button" type="submit" disabled={createMutation.isPending}>Create policy</button>
      </form>
      {query.isError ? <p className="notice">Unable to load policies from the API.</p> : null}
      {createMutation.isError ? <p className="notice">Unable to create policy.</p> : null}
      <Table
        columns={columns}
        rows={rows}
        renderCell={(row, column) => <span>{row[column.key as keyof (typeof rows)[number]]}</span>}
      />
    </Page>
  );
}
