'use client';

import { useState, useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/infrastructure/api/api-client';
import { queryKeys } from '@/infrastructure/api/query-keys';
import { cn } from '@/lib/utils';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface Server {
  id: string;
  hostname: string;
  host: string;
  sshPort: number;
  environment: 'dev' | 'staging' | 'prod';
  role: string;
  status: 'online' | 'offline' | 'maintenance';
  tags: string[];
  description: string;
}

interface ServerFormData {
  hostname: string;
  host: string;
  sshPort: number;
  environment: 'dev' | 'staging' | 'prod';
  role: string;
  tags: string;
  description: string;
}

interface ServersResponse {
  data: Server[];
  total: number;
}

type EnvironmentFilter = 'all' | 'dev' | 'staging' | 'prod';

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const ENVIRONMENTS: { label: string; value: EnvironmentFilter }[] = [
  { label: 'All', value: 'all' },
  { label: 'Dev', value: 'dev' },
  { label: 'Staging', value: 'staging' },
  { label: 'Prod', value: 'prod' },
];

const EMPTY_FORM: ServerFormData = {
  hostname: '',
  host: '',
  sshPort: 22,
  environment: 'dev',
  role: '',
  tags: '',
  description: '',
};

// ---------------------------------------------------------------------------
// Status badge
// ---------------------------------------------------------------------------

function StatusBadge({ status }: { status: Server['status'] }) {
  const styles: Record<Server['status'], string> = {
    online: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
    offline: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
    maintenance: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
  };

  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium capitalize',
        styles[status],
      )}
    >
      {status}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Server form dialog
// ---------------------------------------------------------------------------

function ServerDialog({
  open,
  title,
  form,
  errors,
  saving,
  onClose,
  onChange,
  onSubmit,
}: {
  open: boolean;
  title: string;
  form: ServerFormData;
  errors: Partial<Record<keyof ServerFormData, string>>;
  saving: boolean;
  onClose: () => void;
  onChange: (field: keyof ServerFormData, value: string | number) => void;
  onSubmit: () => void;
}) {
  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* backdrop */}
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />

      {/* dialog */}
      <div className="relative z-10 w-full max-w-lg bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-4">{title}</h2>

        <div className="space-y-4 max-h-[70vh] overflow-y-auto pr-1">
          {/* hostname */}
          <div>
            <label className="block text-sm font-medium mb-1">
              Hostname <span className="text-destructive">*</span>
            </label>
            <input
              type="text"
              value={form.hostname}
              onChange={(e) => onChange('hostname', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.hostname ? 'border-destructive' : 'border-input',
              )}
              placeholder="web-server-01"
            />
            {errors.hostname && (
              <p className="text-xs text-destructive mt-1">{errors.hostname}</p>
            )}
          </div>

          {/* host */}
          <div>
            <label className="block text-sm font-medium mb-1">
              Host (IP) <span className="text-destructive">*</span>
            </label>
            <input
              type="text"
              value={form.host}
              onChange={(e) => onChange('host', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.host ? 'border-destructive' : 'border-input',
              )}
              placeholder="192.168.1.100"
            />
            {errors.host && (
              <p className="text-xs text-destructive mt-1">{errors.host}</p>
            )}
          </div>

          {/* sshPort */}
          <div>
            <label className="block text-sm font-medium mb-1">SSH Port</label>
            <input
              type="number"
              value={form.sshPort}
              onChange={(e) => onChange('sshPort', parseInt(e.target.value, 10) || 22)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
              min={1}
              max={65535}
            />
          </div>

          {/* environment */}
          <div>
            <label className="block text-sm font-medium mb-1">Environment</label>
            <select
              value={form.environment}
              onChange={(e) => onChange('environment', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            >
              <option value="dev">dev</option>
              <option value="staging">staging</option>
              <option value="prod">prod</option>
            </select>
          </div>

          {/* role */}
          <div>
            <label className="block text-sm font-medium mb-1">Role</label>
            <input
              type="text"
              value={form.role}
              onChange={(e) => onChange('role', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
              placeholder="web, db, cache..."
            />
          </div>

          {/* tags */}
          <div>
            <label className="block text-sm font-medium mb-1">Tags</label>
            <input
              type="text"
              value={form.tags}
              onChange={(e) => onChange('tags', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
              placeholder="linux, ubuntu, docker (comma-separated)"
            />
          </div>

          {/* description */}
          <div>
            <label className="block text-sm font-medium mb-1">Description</label>
            <textarea
              value={form.description}
              onChange={(e) => onChange('description', e.target.value)}
              rows={3}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm resize-none"
              placeholder="Optional description..."
            />
          </div>
        </div>

        {/* actions */}
        <div className="flex justify-end gap-3 mt-6 pt-4 border-t">
          <button
            type="button"
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
            disabled={saving}
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={onSubmit}
            disabled={saving}
            className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
          >
            {saving ? 'Saving...' : 'Save'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Delete confirmation dialog
// ---------------------------------------------------------------------------

function DeleteDialog({
  open,
  hostname,
  deleting,
  onClose,
  onConfirm,
}: {
  open: boolean;
  hostname: string;
  deleting: boolean;
  onClose: () => void;
  onConfirm: () => void;
}) {
  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />
      <div className="relative z-10 w-full max-w-sm bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-2">Delete Server</h2>
        <p className="text-sm text-muted-foreground mb-6">
          Are you sure you want to delete <strong>{hostname}</strong>? This action cannot be undone.
        </p>
        <div className="flex justify-end gap-3">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
            disabled={deleting}
          >
            Cancel
          </button>
          <button
            onClick={onConfirm}
            disabled={deleting}
            className="px-4 py-2 text-sm rounded-md bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50"
          >
            {deleting ? 'Deleting...' : 'Delete'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main page component
// ---------------------------------------------------------------------------

export default function ServersPage() {
  const queryClient = useQueryClient();

  // State ----------------------------------------------------------------
  const [envFilter, setEnvFilter] = useState<EnvironmentFilter>('all');
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingServer, setEditingServer] = useState<Server | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<Server | null>(null);
  const [form, setForm] = useState<ServerFormData>({ ...EMPTY_FORM });
  const [errors, setErrors] = useState<Partial<Record<keyof ServerFormData, string>>>({});

  // Queries --------------------------------------------------------------
  const queryParams = envFilter !== 'all' ? { environment: envFilter } : undefined;

  const { data, isLoading, error } = useQuery({
    queryKey: queryKeys.servers.list(queryParams),
    queryFn: () => {
      const qs = envFilter !== 'all' ? `?environment=${envFilter}` : '';
      return apiClient<ServersResponse>(`/api/v1/inventory/servers${qs}`);
    },
  });

  const servers = data?.data ?? [];

  // Mutations ------------------------------------------------------------
  const createMutation = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      apiClient<Server>('/api/v1/inventory/servers', { method: 'POST', body }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.servers.all });
      closeDialog();
    },
  });

  const updateMutation = useMutation({
    mutationFn: ({ id, body }: { id: string; body: Record<string, unknown> }) =>
      apiClient<Server>(`/api/v1/inventory/servers/${id}`, { method: 'PUT', body }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.servers.all });
      closeDialog();
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) =>
      apiClient<void>(`/api/v1/inventory/servers/${id}`, { method: 'DELETE' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.servers.all });
      setDeleteTarget(null);
    },
  });

  // Helpers --------------------------------------------------------------
  const validate = useCallback((): boolean => {
    const next: Partial<Record<keyof ServerFormData, string>> = {};
    if (!form.hostname.trim()) next.hostname = 'Hostname is required';
    if (!form.host.trim()) next.host = 'Host is required';
    setErrors(next);
    return Object.keys(next).length === 0;
  }, [form]);

  const closeDialog = useCallback(() => {
    setDialogOpen(false);
    setEditingServer(null);
    setForm({ ...EMPTY_FORM });
    setErrors({});
  }, []);

  const openAdd = useCallback(() => {
    setEditingServer(null);
    setForm({ ...EMPTY_FORM });
    setErrors({});
    setDialogOpen(true);
  }, []);

  const openEdit = useCallback((server: Server) => {
    setEditingServer(server);
    setForm({
      hostname: server.hostname,
      host: server.host,
      sshPort: server.sshPort,
      environment: server.environment,
      role: server.role,
      tags: (server.tags ?? []).join(', '),
      description: server.description ?? '',
    });
    setErrors({});
    setDialogOpen(true);
  }, []);

  const handleChange = useCallback(
    (field: keyof ServerFormData, value: string | number) => {
      setForm((prev) => ({ ...prev, [field]: value }));
      setErrors((prev) => {
        const next = { ...prev };
        delete next[field];
        return next;
      });
    },
    [],
  );

  const handleSubmit = useCallback(() => {
    if (!validate()) return;
    const body: Record<string, unknown> = {
      hostname: form.hostname.trim(),
      host: form.host.trim(),
      sshPort: form.sshPort,
      environment: form.environment,
      role: form.role.trim(),
      tags: form.tags
        .split(',')
        .map((t) => t.trim())
        .filter(Boolean),
      description: form.description.trim(),
    };

    if (editingServer) {
      updateMutation.mutate({ id: editingServer.id, body });
    } else {
      createMutation.mutate(body);
    }
  }, [form, editingServer, validate, createMutation, updateMutation]);

  const isSaving = createMutation.isPending || updateMutation.isPending;

  // Render ---------------------------------------------------------------
  return (
    <div>
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
        <div>
          <h1 className="text-2xl font-bold">Servers</h1>
          <p className="text-sm text-muted-foreground mt-1">
            Manage server inventory, clusters, and SSH configurations.
          </p>
        </div>
        <button
          onClick={openAdd}
          className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 whitespace-nowrap"
        >
          Add Server
        </button>
      </div>

      {/* Environment filter tabs */}
      <div className="flex gap-1 mb-6 p-1 bg-muted rounded-lg w-fit">
        {ENVIRONMENTS.map((env) => (
          <button
            key={env.value}
            onClick={() => setEnvFilter(env.value)}
            className={cn(
              'px-4 py-1.5 text-sm rounded-md font-medium transition-colors',
              envFilter === env.value
                ? 'bg-background text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground',
            )}
          >
            {env.label}
          </button>
        ))}
      </div>

      {/* Error state */}
      {error && (
        <div className="p-4 mb-4 rounded-md border border-destructive/50 bg-destructive/10 text-destructive text-sm">
          Failed to load servers: {(error as Error).message}
        </div>
      )}

      {/* Loading state */}
      {isLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">
          Loading servers...
        </div>
      )}

      {/* Data table */}
      {!isLoading && !error && (
        <div className="border rounded-lg overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-muted/50">
                  <th className="text-left px-4 py-3 font-medium">Hostname</th>
                  <th className="text-left px-4 py-3 font-medium">Host</th>
                  <th className="text-left px-4 py-3 font-medium">Environment</th>
                  <th className="text-left px-4 py-3 font-medium">Role</th>
                  <th className="text-left px-4 py-3 font-medium">Status</th>
                  <th className="text-right px-4 py-3 font-medium">Actions</th>
                </tr>
              </thead>
              <tbody>
                {servers.length === 0 ? (
                  <tr>
                    <td
                      colSpan={6}
                      className="text-center text-muted-foreground py-12"
                    >
                      No servers found.
                    </td>
                  </tr>
                ) : (
                  servers.map((server) => (
                    <tr
                      key={server.id}
                      className="border-b last:border-b-0 hover:bg-muted/30 transition-colors"
                    >
                      <td className="px-4 py-3 font-medium">{server.hostname}</td>
                      <td className="px-4 py-3 font-mono text-xs">{server.host}</td>
                      <td className="px-4 py-3">
                        <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-muted capitalize">
                          {server.environment}
                        </span>
                      </td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {server.role || '--'}
                      </td>
                      <td className="px-4 py-3">
                        <StatusBadge status={server.status} />
                      </td>
                      <td className="px-4 py-3 text-right">
                        <div className="flex items-center justify-end gap-2">
                          <button
                            onClick={() => openEdit(server)}
                            className="px-3 py-1 text-xs rounded-md border border-input hover:bg-accent transition-colors"
                          >
                            Edit
                          </button>
                          <button
                            onClick={() => setDeleteTarget(server)}
                            className="px-3 py-1 text-xs rounded-md border border-destructive/50 text-destructive hover:bg-destructive/10 transition-colors"
                          >
                            Delete
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Add / Edit dialog */}
      <ServerDialog
        open={dialogOpen}
        title={editingServer ? 'Edit Server' : 'Add Server'}
        form={form}
        errors={errors}
        saving={isSaving}
        onClose={closeDialog}
        onChange={handleChange}
        onSubmit={handleSubmit}
      />

      {/* Delete confirmation dialog */}
      <DeleteDialog
        open={!!deleteTarget}
        hostname={deleteTarget?.hostname ?? ''}
        deleting={deleteMutation.isPending}
        onClose={() => setDeleteTarget(null)}
        onConfirm={() => {
          if (deleteTarget) deleteMutation.mutate(deleteTarget.id);
        }}
      />
    </div>
  );
}
