'use client';

import { useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
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 HookScript {
  id: string;
  name: string;
  event: 'PreToolUse' | 'PostToolUse' | 'PreNotification' | 'PostNotification';
  toolPattern: string;
  script: string;
  timeout: number;
  enabled: boolean;
  description: string;
  createdAt: string;
  updatedAt: string;
}

interface HookFormData {
  name: string;
  event: HookScript['event'];
  toolPattern: string;
  script: string;
  timeout: number;
  enabled: boolean;
  description: string;
}

type HooksResponse = HookScript[];

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

const EVENT_TYPES: HookScript['event'][] = [
  'PreToolUse',
  'PostToolUse',
  'PreNotification',
  'PostNotification',
];

const EVENT_BADGE_STYLES: Record<HookScript['event'], string> = {
  PreToolUse: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
  PostToolUse: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
  PreNotification: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
  PostNotification: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900/30 dark:text-indigo-400',
};

const EMPTY_FORM: HookFormData = {
  name: '',
  event: 'PreToolUse',
  toolPattern: '*',
  script: '',
  timeout: 30,
  enabled: true,
  description: '',
};

// ---------------------------------------------------------------------------
// Event badge
// ---------------------------------------------------------------------------

function EventBadge({ event }: { event: HookScript['event'] }) {
  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium',
        EVENT_BADGE_STYLES[event],
      )}
    >
      {event}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Hook form dialog
// ---------------------------------------------------------------------------

function HookDialog({
  open,
  title,
  form,
  errors,
  saving,
  onClose,
  onChange,
  onSubmit,
}: {
  open: boolean;
  title: string;
  form: HookFormData;
  errors: Partial<Record<keyof HookFormData, string>>;
  saving: boolean;
  onClose: () => void;
  onChange: (field: keyof HookFormData, value: string | number | boolean) => void;
  onSubmit: () => void;
}) {
  const { t } = useTranslation('agent-config');
  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-2xl 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('hooks.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="pre-bash-audit"
            />
            {errors.name && (
              <p className="text-xs text-destructive mt-1">{errors.name}</p>
            )}
          </div>

          {/* event type */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('hooks.form.eventType')}</label>
            <select
              value={form.event}
              onChange={(e) => onChange('event', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            >
              {EVENT_TYPES.map((evt) => (
                <option key={evt} value={evt}>
                  {evt}
                </option>
              ))}
            </select>
          </div>

          {/* tool pattern */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('hooks.form.toolPattern')}</label>
            <input
              type="text"
              value={form.toolPattern}
              onChange={(e) => onChange('toolPattern', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
              placeholder="Bash, *, Read,Write"
            />
            <p className="text-xs text-muted-foreground mt-1">
              Comma-separated tool names or * for all tools
            </p>
          </div>

          {/* script content */}
          <div>
            <label className="block text-sm font-medium mb-1">
              {t('hooks.form.script')} <span className="text-destructive">*</span>
            </label>
            <textarea
              value={form.script}
              onChange={(e) => onChange('script', e.target.value)}
              className={cn(
                'w-full min-h-[300px] bg-gray-950 text-green-400 font-mono text-sm p-4 rounded-md border resize-y',
                errors.script ? 'border-destructive' : 'border-input',
              )}
              placeholder={'#!/bin/bash\n# Hook script body\n# Exit 0 to allow, non-zero to block (PreToolUse only)'}
              spellCheck={false}
            />
            {errors.script && (
              <p className="text-xs text-destructive mt-1">{errors.script}</p>
            )}
          </div>

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

          {/* enabled toggle */}
          <div className="flex items-center gap-3">
            <label className="text-sm font-medium">{t('hooks.form.enabled')}</label>
            <button
              type="button"
              role="switch"
              aria-checked={form.enabled}
              onClick={() => onChange('enabled', !form.enabled)}
              className={cn(
                'relative inline-flex h-6 w-11 items-center rounded-full transition-colors',
                form.enabled ? 'bg-primary' : 'bg-muted',
              )}
            >
              <span
                className={cn(
                  'inline-block h-4 w-4 rounded-full bg-white transition-transform',
                  form.enabled ? 'translate-x-6' : 'translate-x-1',
                )}
              />
            </button>
          </div>

          {/* description */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('hooks.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 of what this hook does..."
            />
          </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,
  hookName,
  deleting,
  onClose,
  onConfirm,
}: {
  open: boolean;
  hookName: string;
  deleting: boolean;
  onClose: () => void;
  onConfirm: () => void;
}) {
  const { t } = useTranslation('agent-config');
  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('hooks.deleteHook')}</h2>
        <p className="text-sm text-muted-foreground mb-6">
          {tc('confirmDelete')} <strong>{hookName}</strong>
        </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 HooksPage() {
  const { t } = useTranslation('agent-config');
  const { t: tc } = useTranslation('common');
  const queryClient = useQueryClient();

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

  // Queries --------------------------------------------------------------
  const { data, isLoading, error } = useQuery({
    queryKey: queryKeys.hooks.list(),
    queryFn: () => apiClient<HooksResponse>('/api/v1/agent/hooks'),
  });

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

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

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

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

  const toggleMutation = useMutation({
    mutationFn: ({ id, enabled }: { id: string; enabled: boolean }) =>
      apiClient<HookScript>(`/api/v1/agent/hooks/${id}`, {
        method: 'PUT',
        body: { enabled },
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.hooks.all });
    },
  });

  // Helpers --------------------------------------------------------------
  const validate = useCallback((): boolean => {
    const next: Partial<Record<keyof HookFormData, string>> = {};
    if (!form.name.trim()) next.name = 'Name is required';
    if (!form.script.trim()) next.script = 'Script content is required';
    setErrors(next);
    return Object.keys(next).length === 0;
  }, [form]);

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

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

  const openEdit = useCallback((hook: HookScript) => {
    setEditingHook(hook);
    setForm({
      name: hook.name,
      event: hook.event,
      toolPattern: hook.toolPattern,
      script: hook.script,
      timeout: hook.timeout,
      enabled: hook.enabled,
      description: hook.description ?? '',
    });
    setErrors({});
    setDialogOpen(true);
  }, []);

  const handleChange = useCallback(
    (field: keyof HookFormData, value: string | number | boolean) => {
      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> = {
      name: form.name.trim(),
      event: form.event,
      toolPattern: form.toolPattern.trim(),
      script: form.script,
      timeout: form.timeout,
      enabled: form.enabled,
      description: form.description.trim(),
    };

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

      {/* Info banner */}
      <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4 mb-6">
        <p className="text-sm text-blue-800 dark:text-blue-200">
          {t('hooks.infoBanner')}
        </p>
      </div>

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

      {/* Loading state */}
      {isLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">
          {t('hooks.loading')}
        </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">{t('hooks.table.name')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('hooks.table.event')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('hooks.table.toolPattern')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('hooks.table.script')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('hooks.table.enabled')}</th>
                  <th className="text-right px-4 py-3 font-medium">{t('hooks.table.actions')}</th>
                </tr>
              </thead>
              <tbody>
                {hooks.length === 0 ? (
                  <tr>
                    <td
                      colSpan={6}
                      className="text-center text-muted-foreground py-12"
                    >
                      {t('hooks.empty')}
                    </td>
                  </tr>
                ) : (
                  hooks.map((hook) => (
                    <tr
                      key={hook.id}
                      className="border-b last:border-b-0 hover:bg-muted/30 transition-colors"
                    >
                      <td className="px-4 py-3 font-medium">{hook.name}</td>
                      <td className="px-4 py-3">
                        <EventBadge event={hook.event} />
                      </td>
                      <td className="px-4 py-3 font-mono text-xs">
                        {hook.toolPattern || '*'}
                      </td>
                      <td className="px-4 py-3 text-muted-foreground text-xs">
                        {hook.script
                          ? `${hook.script.split('\n').length} lines`
                          : '--'}
                      </td>
                      <td className="px-4 py-3">
                        <button
                          type="button"
                          role="switch"
                          aria-checked={hook.enabled}
                          onClick={() =>
                            toggleMutation.mutate({
                              id: hook.id,
                              enabled: !hook.enabled,
                            })
                          }
                          className={cn(
                            'relative inline-flex h-5 w-9 items-center rounded-full transition-colors',
                            hook.enabled ? 'bg-primary' : 'bg-muted',
                          )}
                        >
                          <span
                            className={cn(
                              'inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform',
                              hook.enabled ? 'translate-x-[18px]' : 'translate-x-[2px]',
                            )}
                          />
                        </button>
                      </td>
                      <td className="px-4 py-3 text-right">
                        <div className="flex items-center justify-end gap-2">
                          <button
                            onClick={() => openEdit(hook)}
                            className="px-3 py-1 text-xs rounded-md border border-input hover:bg-accent transition-colors"
                          >
                            {tc('edit')}
                          </button>
                          <button
                            onClick={() => setDeleteTarget(hook)}
                            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>
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Add / Edit dialog */}
      <HookDialog
        open={dialogOpen}
        title={editingHook ? t('hooks.editHook') : t('hooks.addHook')}
        form={form}
        errors={errors}
        saving={isSaving}
        onClose={closeDialog}
        onChange={handleChange}
        onSubmit={handleSubmit}
      />

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