"use client";

import { useEffect, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { api, auth as authApi, type InstanceUser, type Role } from "@/lib/api";
import { useAuth } from "@/components/AuthProvider";
import { Badge, Button, Card, Modal, Table, Tbody, Td, Th, Thead, Tr } from "@/components/ui";

const ROLES: Role[] = ["owner", "admin", "member"];

const inputClass =
  "w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30";

function Field({ label, hint, children }: { label: string; hint?: string; children: React.ReactNode }) {
  return (
    <div>
      <label className="mb-1.5 block text-sm font-medium text-text-secondary">{label}</label>
      {children}
      {hint && <p className="mt-1 text-xs text-text-tertiary">{hint}</p>}
    </div>
  );
}

function roleVariant(role: Role) {
  if (role === "owner") return "accent" as const;
  if (role === "admin") return "warning" as const;
  return "neutral" as const;
}

function MembersCard() {
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const [addOpen, setAddOpen] = useState(false);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [role, setRole] = useState<Role>("member");

  const { data: users, isLoading, error } = useQuery({ queryKey: ["instance-users"], queryFn: api.listInstanceUsers });

  const invalidate = () => queryClient.invalidateQueries({ queryKey: ["instance-users"] });

  const { mutate: createUser, isPending: creating, error: createError } = useMutation({
    mutationFn: () => api.createInstanceUser({ email, password, role }),
    onSuccess: () => {
      invalidate();
      setAddOpen(false);
      setEmail("");
      setPassword("");
      setRole("member");
    },
  });

  const { mutate: changeRole, error: roleError } = useMutation({
    mutationFn: ({ userId, next }: { userId: string; next: Role }) => api.updateInstanceUserRole(userId, next),
    onSuccess: invalidate,
    
    
    onError: invalidate,
  });

  const { mutate: removeUser, error: removeError } = useMutation({
    mutationFn: (userId: string) => api.deleteInstanceUser(userId),
    onSuccess: invalidate,
  });

  const actionError = (roleError ?? removeError) as Error | null;

  
  
  const isOwner = user?.role === "owner";
  const assignableRoles = isOwner ? ROLES : ROLES.filter((r) => r !== "owner");

  return (
    <Card>
      <div className="mb-4 flex items-start justify-between gap-3">
        <div>
          <h2 className="text-base font-semibold text-text-primary">Members</h2>
          <p className="mt-0.5 text-sm text-text-secondary">
            People with access to this instance. Owners and admins can manage settings.
          </p>
        </div>
        <Button variant="primary" size="sm" onClick={() => setAddOpen(true)}>
          Add Member
        </Button>
      </div>

      {actionError && (
        <div className="mb-4 rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">
          {actionError.message}
        </div>
      )}

      {isLoading ? (
        <div className="flex justify-center py-8">
          <div className="h-6 w-6 animate-spin rounded-full border-2 border-border border-t-accent" />
        </div>
      ) : error ? (
        <p className="py-6 text-sm text-danger">{(error as Error).message}</p>
      ) : !users || users.length === 0 ? (
        <p className="py-6 text-sm text-text-secondary">No members yet.</p>
      ) : (
        <Table>
          <Thead>
            <Tr>
              <Th>Email</Th>
              <Th>Role</Th>
              <Th>Sign-in</Th>
              <Th>Last login</Th>
              <Th className="text-right">Actions</Th>
            </Tr>
          </Thead>
          <Tbody>
            {users.map((u: InstanceUser) => {
              const isSelf = u.user_id === user?.user_id;
              
              const locked = isSelf || (u.role === "owner" && !isOwner);
              return (
                <Tr key={u.user_id}>
                  <Td>
                    <span className="font-medium">{u.email}</span>
                    {isSelf && <span className="ml-2 text-xs text-text-tertiary">(you)</span>}
                  </Td>
                  <Td>
                    {locked ? (
                      <Badge variant={roleVariant(u.role)}>{u.role}</Badge>
                    ) : (
                      <select
                        value={u.role}
                        onChange={(e) => changeRole({ userId: u.user_id, next: e.target.value as Role })}
                        className="rounded-lg border border-border bg-surface-2 px-2 py-1 text-sm text-text-primary focus:border-accent/50 focus:outline-none"
                      >
                        {assignableRoles.map((r) => (
                          <option key={r} value={r}>
                            {r}
                          </option>
                        ))}
                      </select>
                    )}
                  </Td>
                  <Td>
                    <Badge variant="neutral">{u.auth_source === "oidc" ? "SSO" : "Password"}</Badge>
                  </Td>
                  <Td className="text-text-secondary">
                    {u.last_login ? new Date(u.last_login).toLocaleString() : "Never"}
                  </Td>
                  <Td className="text-right">
                    {!locked && (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm(`Remove ${u.email} from this instance?`)) removeUser(u.user_id);
                        }}
                      >
                        Remove
                      </Button>
                    )}
                  </Td>
                </Tr>
              );
            })}
          </Tbody>
        </Table>
      )}

      <Modal open={addOpen} title="Add Member" onClose={() => setAddOpen(false)}>
        <form
          onSubmit={(e) => {
            e.preventDefault();
            createUser();
          }}
          className="space-y-4"
        >
          <Field label="Email">
            <input
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className={inputClass}
            />
          </Field>

          <Field
            label="Password"
            hint="Leave blank if this member will sign in through SSO instead."
          >
            <input
              type="password"
              autoComplete="new-password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              className={inputClass}
            />
          </Field>

          <Field label="Role">
            <select value={role} onChange={(e) => setRole(e.target.value as Role)} className={inputClass}>
              {assignableRoles.map((r) => (
                <option key={r} value={r}>
                  {r}
                </option>
              ))}
            </select>
          </Field>

          {createError && (
            <div className="rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">
              {(createError as Error).message}
            </div>
          )}

          <div className="flex justify-end gap-2">
            <Button type="button" variant="ghost" onClick={() => setAddOpen(false)}>
              Cancel
            </Button>
            <Button type="submit" variant="primary" loading={creating}>
              Add Member
            </Button>
          </div>
        </form>
      </Modal>
    </Card>
  );
}

function OIDCCard() {
  const queryClient = useQueryClient();
  const { data: cfg, isLoading } = useQuery({ queryKey: ["instance-oidc"], queryFn: api.getInstanceOIDC });

  const [issuer, setIssuer] = useState("");
  const [clientId, setClientId] = useState("");
  const [clientSecret, setClientSecret] = useState("");
  const [enabled, setEnabled] = useState(false);
  const [saved, setSaved] = useState(false);
  const [copied, setCopied] = useState(false);

  const redirectUrl = authApi.oidcRedirectUrl();

  useEffect(() => {
    if (!cfg) return;
    setIssuer(cfg.issuer ?? "");
    setClientId(cfg.client_id ?? "");
    setEnabled(cfg.enabled);
    
    setClientSecret("");
  }, [cfg]);

  const { mutate: save, isPending, error } = useMutation({
    mutationFn: () => api.saveInstanceOIDC({ issuer, client_id: clientId, client_secret: clientSecret, enabled }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["instance-oidc"] });
      setClientSecret("");
      setSaved(true);
      setTimeout(() => setSaved(false), 3000);
    },
  });

  async function copyRedirect() {
    await navigator.clipboard.writeText(redirectUrl);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  }

  if (isLoading) {
    return (
      <Card>
        <div className="flex justify-center py-8">
          <div className="h-6 w-6 animate-spin rounded-full border-2 border-border border-t-accent" />
        </div>
      </Card>
    );
  }

  const secretSet = cfg?.client_secret_set ?? false;

  return (
    <Card>
      <div className="mb-4">
        <h2 className="text-base font-semibold text-text-primary">Single Sign-On (OIDC)</h2>
        <p className="mt-0.5 text-sm text-text-secondary">
          Let members sign in with your identity provider. Users are provisioned into this instance on
          first sign-in.
        </p>
      </div>

      <div className="mb-5 rounded-lg border border-border bg-surface-2 p-3">
        <p className="mb-2 text-xs font-medium text-text-secondary">
          Register this redirect URL with your provider:
        </p>
        <div className="flex items-center gap-2">
          <code className="flex-1 overflow-x-auto rounded bg-background px-2 py-1.5 font-mono text-xs text-text-primary">
            {redirectUrl}
          </code>
          <Button type="button" variant="ghost" size="sm" onClick={copyRedirect}>
            {copied ? "Copied!" : "Copy"}
          </Button>
        </div>
      </div>

      <form
        onSubmit={(e) => {
          e.preventDefault();
          save();
        }}
        className="space-y-4"
      >
        <Field label="Issuer URL" hint="The provider's OIDC discovery base, e.g. https://accounts.google.com">
          <input
            type="url"
            required
            value={issuer}
            onChange={(e) => setIssuer(e.target.value)}
            className={inputClass}
          />
        </Field>

        <Field label="Client ID">
          <input
            type="text"
            required
            value={clientId}
            onChange={(e) => setClientId(e.target.value)}
            className={inputClass}
          />
        </Field>

        <Field
          label="Client Secret"
          hint={
            secretSet
              ? "A secret is stored. Leave this blank to keep it, or enter a new one to replace it."
              : "No secret stored yet."
          }
        >
          <input
            type="password"
            autoComplete="new-password"
            placeholder={secretSet ? "•••••••• (unchanged)" : "Enter client secret"}
            value={clientSecret}
            onChange={(e) => setClientSecret(e.target.value)}
            className={inputClass}
          />
        </Field>

        <div className="flex items-center gap-2 text-sm">
          <span className={`inline-block h-2 w-2 rounded-full ${secretSet ? "bg-success" : "bg-text-tertiary"}`} />
          <span className="text-text-secondary">
            {secretSet ? "Client secret is configured" : "No client secret configured"}
          </span>
        </div>

        <label className="flex items-center gap-2 text-sm text-text-secondary">
          <input
            type="checkbox"
            checked={enabled}
            onChange={(e) => setEnabled(e.target.checked)}
            className="h-4 w-4 rounded border-border bg-surface-2 accent-accent"
          />
          Enable SSO sign-in for this instance
        </label>

        {enabled && !secretSet && !clientSecret && (
          <div className="rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-sm text-warning">
            SSO cannot complete sign-in without a client secret.
          </div>
        )}

        {error && (
          <div className="rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">
            {(error as Error).message}
          </div>
        )}

        <div className="flex items-center gap-3">
          <Button type="submit" variant="primary" loading={isPending}>
            {saved ? "Saved!" : "Save SSO Settings"}
          </Button>
          {saved && <span className="text-sm text-success">SSO settings saved.</span>}
        </div>
      </form>
    </Card>
  );
}

export default function InstanceSettingsPage() {
  const { instance, isAdmin } = useAuth();

  if (!isAdmin) {
    return (
      <div className="p-8">
        <Card className="max-w-lg">
          <h1 className="text-base font-semibold text-text-primary">You don&apos;t have access</h1>
          <p className="mt-1 text-sm text-text-secondary">
            Instance settings are available to owners and admins only. Ask an administrator if you need
            access.
          </p>
        </Card>
      </div>
    );
  }

  return (
    <div className="p-8">
      <div className="mb-8">
        <h1 className="text-2xl font-bold text-text-primary">Instance</h1>
        <p className="mt-1 text-sm text-text-secondary">
          {instance ? `Manage members and sign-in for ${instance.name}.` : "Manage members and sign-in."}
        </p>
      </div>

      <div className="space-y-6">
        <MembersCard />
        <OIDCCard />
      </div>
    </div>
  );
}
