'use client';

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

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

interface Cluster {
  id: string;
  name: string;
  description: string;
  environment: 'dev' | 'staging' | 'prod';
  tags: string[];
  serverIds: string[];
  serverCount: number;
  healthySummary: { online: number; offline: number; maintenance: number };
  createdAt: string;
  updatedAt: string;
}

interface Server {
  id: string;
  hostname: string;
  host: string;
  status: 'online' | 'offline' | 'maintenance';
  environment: string;
}

type ClustersResponse = Cluster[];

type ServersResponse = Server[];

interface ClusterFormData {
  name: string;
  description: string;
  environment: 'dev' | 'staging' | 'prod';
  tags: string;
  serverIds: string[];
}

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

const EMPTY_FORM: ClusterFormData = {
  name: '',
  description: '',
  environment: 'dev',
  tags: '',
  serverIds: [],
};

const CLUSTER_QUERY_KEY = ['clusters'] as const;

const ENV_COLORS: Record<string, string> = {
  dev: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
  staging: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
  prod: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
};

// ---------------------------------------------------------------------------
// Environment badge
// ---------------------------------------------------------------------------

function EnvironmentBadge({ environment }: { environment: string }) {
  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium capitalize',
        ENV_COLORS[environment] ?? 'bg-muted text-muted-foreground',
      )}
    >
      {environment}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Health summary dots
// ---------------------------------------------------------------------------

function HealthSummary({
  summary,
}: {
  summary: Cluster['healthySummary'];
}) {
  const { t } = useTranslation('servers');

  const parts: { count: number; labelKey: string; color: string }[] = [];
  if (summary.online > 0) {
    parts.push({ count: summary.online, labelKey: 'clusters.health.online', color: 'bg-green-500' });
  }
  if (summary.offline > 0) {
    parts.push({ count: summary.offline, labelKey: 'clusters.health.offline', color: 'bg-red-500' });
  }
  if (summary.maintenance > 0) {
    parts.push({ count: summary.maintenance, labelKey: 'clusters.health.maintenance', color: 'bg-yellow-500' });
  }

  if (parts.length === 0) {
    return (
      <span className="text-xs text-muted-foreground">{t('clusters.health.noServers')}</span>
    );
  }

  return (
    <div className="flex items-center gap-3">
      {parts.map((part) => (
        <span key={part.labelKey} className="inline-flex items-center gap-1 text-xs text-muted-foreground">
          <span className={cn('w-2 h-2 rounded-full', part.color)} />
          {part.count} {t(part.labelKey)}
        </span>
      ))}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Cluster form dialog
// ---------------------------------------------------------------------------

function ClusterDialog({
  open,
  title,
  form,
  errors,
  saving,
  servers,
  serversLoading,
  onClose,
  onChange,
  onToggleServer,
  onSubmit,
}: {
  open: boolean;
  title: string;
  form: ClusterFormData;
  errors: Partial<Record<keyof ClusterFormData, string>>;
  saving: boolean;
  servers: Server[];
  serversLoading: boolean;
  onClose: () => void;
  onChange: (field: keyof ClusterFormData, value: string) => void;
  onToggleServer: (serverId: string) => void;
  onSubmit: () => void;
}) {
  const { t } = useTranslation('servers');
  const { t: tc } = useTranslation('common');

  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">
          {/* name */}
          <div>
            <label className="block text-sm font-medium mb-1">
              {t('clusters.form.name')} <span className="text-destructive">*</span>
            </label>
            <input
              type="text"
              value={form.name}
              onChange={(e) => onChange('name', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.name ? 'border-destructive' : 'border-input',
              )}
              placeholder="Production Web Tier"
            />
            {errors.name && (
              <p className="text-xs text-destructive mt-1">{errors.name}</p>
            )}
          </div>

          {/* description */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('clusters.form.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 for this cluster..."
            />
          </div>

          {/* environment */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('clusters.form.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>

          {/* tags */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('clusters.form.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="web, nginx, load-balanced (comma-separated)"
            />
          </div>

          {/* server selection */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('clusters.form.servers')}</label>
            {serversLoading ? (
              <div className="text-xs text-muted-foreground py-4 text-center">
                {tc('loading')}
              </div>
            ) : servers.length === 0 ? (
              <div className="text-xs text-muted-foreground py-4 text-center">
                {tc('noData')}
              </div>
            ) : (
              <div className="max-h-[200px] overflow-y-auto border border-input rounded-md">
                {servers.map((server) => (
                  <label
                    key={server.id}
                    className="flex items-center gap-3 px-3 py-2 hover:bg-muted/30 cursor-pointer border-b last:border-b-0 transition-colors"
                  >
                    <input
                      type="checkbox"
                      checked={form.serverIds.includes(server.id)}
                      onChange={() => onToggleServer(server.id)}
                      className="rounded border-input"
                    />
                    <div className="flex-1 min-w-0">
                      <span className="text-sm font-medium">{server.hostname}</span>
                      <span className="text-xs text-muted-foreground ml-2 font-mono">
                        {server.host}
                      </span>
                    </div>
                    <span
                      className={cn(
                        'w-2 h-2 rounded-full flex-shrink-0',
                        server.status === 'online'
                          ? 'bg-green-500'
                          : server.status === 'offline'
                            ? 'bg-red-500'
                            : 'bg-yellow-500',
                      )}
                    />
                  </label>
                ))}
              </div>
            )}
            {form.serverIds.length > 0 && (
              <p className="text-xs text-muted-foreground mt-1">
                {form.serverIds.length} server{form.serverIds.length !== 1 ? 's' : ''} selected
              </p>
            )}
          </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}
          >
            {tc('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 ? tc('saving') : tc('save')}
          </button>
        </div>
      </div>
    </div>
  );
}

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

function DeleteDialog({
  open,
  clusterName,
  deleting,
  onClose,
  onConfirm,
}: {
  open: boolean;
  clusterName: string;
  deleting: boolean;
  onClose: () => void;
  onConfirm: () => void;
}) {
  const { t } = useTranslation('servers');
  const { t: tc } = useTranslation('common');

  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">{t('clusters.deleteCluster')}</h2>
        <p className="text-sm text-muted-foreground mb-6">
          {t('dialog.deleteConfirm')} <strong>{clusterName}</strong>? {t('dialog.deleteWarning')}
        </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}
          >
            {tc('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 ? tc('deleting') : tc('delete')}
          </button>
        </div>
      </div>
    </div>
  );
}

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

export default function ClustersPage() {
  const { t } = useTranslation('servers');
  const { t: tc } = useTranslation('common');
  const queryClient = useQueryClient();

  // State ----------------------------------------------------------------
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingCluster, setEditingCluster] = useState<Cluster | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<Cluster | null>(null);
  const [form, setForm] = useState<ClusterFormData>({ ...EMPTY_FORM });
  const [errors, setErrors] = useState<Partial<Record<keyof ClusterFormData, string>>>({});

  // Queries --------------------------------------------------------------
  const { data, isLoading, error } = useQuery({
    queryKey: CLUSTER_QUERY_KEY,
    queryFn: () => apiClient<ClustersResponse>('/api/v1/inventory/clusters'),
  });

  const clusters = Array.isArray(data) ? data : [];

  // Fetch servers for the dialog server selection
  const { data: serversData, isLoading: serversLoading } = useQuery({
    queryKey: queryKeys.servers.list(),
    queryFn: () => apiClient<ServersResponse>('/api/v1/inventory/servers'),
    enabled: dialogOpen,
  });

  const servers = Array.isArray(serversData) ? serversData : [];

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

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

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

  // Helpers --------------------------------------------------------------
  const validate = useCallback((): boolean => {
    const next: Partial<Record<keyof ClusterFormData, string>> = {};
    if (!form.name.trim()) next.name = t('validation.hostnameRequired');
    setErrors(next);
    return Object.keys(next).length === 0;
  }, [form]);

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

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

  const openEdit = useCallback((cluster: Cluster) => {
    setEditingCluster(cluster);
    setForm({
      name: cluster.name,
      description: cluster.description ?? '',
      environment: cluster.environment,
      tags: (cluster.tags ?? []).join(', '),
      serverIds: cluster.serverIds ?? [],
    });
    setErrors({});
    setDialogOpen(true);
  }, []);

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

  const handleToggleServer = useCallback((serverId: string) => {
    setForm((prev) => {
      const exists = prev.serverIds.includes(serverId);
      return {
        ...prev,
        serverIds: exists
          ? prev.serverIds.filter((id) => id !== serverId)
          : [...prev.serverIds, serverId],
      };
    });
  }, []);

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

    if (editingCluster) {
      updateMutation.mutate({ id: editingCluster.id, body });
    } else {
      createMutation.mutate(body);
    }
  }, [form, editingCluster, 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">{t('clusters.title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">
            {t('clusters.subtitle')}
          </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"
        >
          {t('clusters.addCluster')}
        </button>
      </div>

      {/* Error state */}
      {error && (
        <div className="p-4 mb-4 rounded-md border border-destructive/50 bg-destructive/10 text-destructive text-sm">
          {t('clusters.loadError')} {(error as Error).message}
        </div>
      )}

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

      {/* Empty state */}
      {!isLoading && !error && clusters.length === 0 && (
        <div className="text-center py-12 text-muted-foreground">
          <p className="text-sm">{t('clusters.empty')}</p>
          <p className="text-xs mt-1">{t('clusters.subtitle')}</p>
        </div>
      )}

      {/* Cluster cards grid */}
      {!isLoading && !error && clusters.length > 0 && (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {clusters.map((cluster) => (
            <div
              key={cluster.id}
              className="bg-card border rounded-lg p-4 hover:shadow-sm transition-shadow"
            >
              {/* Card header: name + environment */}
              <div className="flex items-start justify-between gap-2 mb-2">
                <h3 className="font-semibold text-base truncate">{cluster.name}</h3>
                <EnvironmentBadge environment={cluster.environment} />
              </div>

              {/* Description */}
              {cluster.description && (
                <p className="text-sm text-muted-foreground mb-3 line-clamp-2">
                  {cluster.description}
                </p>
              )}

              {/* Server count badge */}
              <div className="flex items-center gap-2 mb-3">
                <span className="inline-flex items-center bg-muted px-2 py-0.5 rounded text-xs font-medium">
                  {cluster.serverCount} server{cluster.serverCount !== 1 ? 's' : ''}
                </span>
              </div>

              {/* Tags */}
              {cluster.tags && cluster.tags.length > 0 && (
                <div className="flex flex-wrap gap-1 mb-3">
                  {cluster.tags.map((tag) => (
                    <span
                      key={tag}
                      className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-muted/60 text-muted-foreground"
                    >
                      {tag}
                    </span>
                  ))}
                </div>
              )}

              {/* Health summary */}
              <div className="mb-4">
                <HealthSummary summary={cluster.healthySummary} />
              </div>

              {/* Actions */}
              <div className="flex items-center justify-end gap-2 pt-3 border-t">
                <button
                  onClick={() => openEdit(cluster)}
                  className="px-3 py-1 text-xs rounded-md border border-input hover:bg-accent transition-colors"
                >
                  {tc('edit')}
                </button>
                <button
                  onClick={() => setDeleteTarget(cluster)}
                  className="px-3 py-1 text-xs rounded-md border border-destructive/50 text-destructive hover:bg-destructive/10 transition-colors"
                >
                  {tc('delete')}
                </button>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Add / Edit dialog */}
      <ClusterDialog
        open={dialogOpen}
        title={editingCluster ? t('clusters.editCluster') : t('clusters.addCluster')}
        form={form}
        errors={errors}
        saving={isSaving}
        servers={servers}
        serversLoading={serversLoading}
        onClose={closeDialog}
        onChange={handleChange}
        onToggleServer={handleToggleServer}
        onSubmit={handleSubmit}
      />

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