'use client';

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

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

interface Skill {
  id: string;
  name: string;
  description: string;
  category: 'inspection' | 'deployment' | 'maintenance' | 'security' | 'monitoring' | 'custom';
  script: string;
  tags: string[];
  enabled: boolean;
  createdAt: string;
  updatedAt: string;
}

interface SkillFormData {
  name: string;
  description: string;
  category: Skill['category'];
  script: string;
  tags: string;
  enabled: boolean;
}

interface SkillsResponse {
  data: Skill[];
  total: number;
}

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

const SKILL_QUERY_KEY = ['skills'] as const;

const CATEGORIES: { label: string; value: Skill['category'] }[] = [
  { label: 'Inspection', value: 'inspection' },
  { label: 'Deployment', value: 'deployment' },
  { label: 'Maintenance', value: 'maintenance' },
  { label: 'Security', value: 'security' },
  { label: 'Monitoring', value: 'monitoring' },
  { label: 'Custom', value: 'custom' },
];

const CATEGORY_STYLES: Record<Skill['category'], string> = {
  inspection: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
  deployment: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
  maintenance: 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-400',
  security: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
  monitoring: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
  custom: 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400',
};

const EMPTY_FORM: SkillFormData = {
  name: '',
  description: '',
  category: 'custom',
  script: '',
  tags: '',
  enabled: true,
};

// ---------------------------------------------------------------------------
// Category badge
// ---------------------------------------------------------------------------

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

// ---------------------------------------------------------------------------
// Enabled / Disabled badge
// ---------------------------------------------------------------------------

function EnabledBadge({ enabled }: { enabled: boolean }) {
  return (
    <span
      className={cn(
        'inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium',
        enabled
          ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'
          : 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400',
      )}
    >
      {enabled ? 'Enabled' : 'Disabled'}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Skill form dialog
// ---------------------------------------------------------------------------

function SkillDialog({
  open,
  title,
  form,
  errors,
  saving,
  onClose,
  onChange,
  onSubmit,
}: {
  open: boolean;
  title: string;
  form: SkillFormData;
  errors: Partial<Record<keyof SkillFormData, string>>;
  saving: boolean;
  onClose: () => void;
  onChange: (field: keyof SkillFormData, value: string | boolean) => 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">
          {/* name */}
          <div>
            <label className="block text-sm font-medium mb-1">
              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="check-disk-usage"
            />
            {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">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="What does this skill do..."
            />
          </div>

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

          {/* script */}
          <div>
            <label className="block text-sm font-medium mb-1">Script</label>
            <textarea
              value={form.script}
              onChange={(e) => onChange('script', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm font-mono min-h-[200px] resize-y"
              placeholder={"#!/bin/bash\n# Skill script content..."}
            />
          </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="disk, health, linux (comma-separated)"
            />
          </div>

          {/* enabled toggle */}
          <div className="flex items-center gap-3">
            <label className="relative inline-flex items-center cursor-pointer">
              <input
                type="checkbox"
                checked={form.enabled}
                onChange={(e) => onChange('enabled', e.target.checked)}
                className="sr-only peer"
              />
              <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-ring rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:after:border-gray-600 peer-checked:bg-primary" />
            </label>
            <span className="text-sm font-medium">Enabled</span>
          </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,
  skillName,
  deleting,
  onClose,
  onConfirm,
}: {
  open: boolean;
  skillName: 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 Skill</h2>
        <p className="text-sm text-muted-foreground mb-6">
          Are you sure you want to delete <strong>{skillName}</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 SkillsPage() {
  const queryClient = useQueryClient();

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

  // Queries --------------------------------------------------------------
  const { data, isLoading, error } = useQuery({
    queryKey: SKILL_QUERY_KEY,
    queryFn: () => apiClient<SkillsResponse>('/api/v1/agent/skills'),
  });

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

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

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

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

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

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

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

  const openEdit = useCallback((skill: Skill) => {
    setEditingSkill(skill);
    setForm({
      name: skill.name,
      description: skill.description ?? '',
      category: skill.category,
      script: skill.script ?? '',
      tags: (skill.tags ?? []).join(', '),
      enabled: skill.enabled,
    });
    setErrors({});
    setDialogOpen(true);
  }, []);

  const handleChange = useCallback(
    (field: keyof SkillFormData, value: string | 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(),
      description: form.description.trim(),
      category: form.category,
      script: form.script,
      tags: form.tags
        .split(',')
        .map((t) => t.trim())
        .filter(Boolean),
      enabled: form.enabled,
    };

    if (editingSkill) {
      updateMutation.mutate({ id: editingSkill.id, body });
    } else {
      createMutation.mutate(body);
    }
  }, [form, editingSkill, 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">Skills</h1>
          <p className="text-sm text-muted-foreground mt-1">
            Manage Claude Code skills for the AI agent
          </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 Skill
        </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 skills: {(error as Error).message}
        </div>
      )}

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

      {/* Empty state */}
      {!isLoading && !error && skills.length === 0 && (
        <div className="text-center py-12">
          <p className="text-sm text-muted-foreground mb-4">
            No skills configured yet. Add your first skill to get started.
          </p>
          <button
            onClick={openAdd}
            className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90"
          >
            Add Skill
          </button>
        </div>
      )}

      {/* Skills grid */}
      {!isLoading && !error && skills.length > 0 && (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {skills.map((skill) => (
            <div
              key={skill.id}
              className="bg-card border rounded-lg p-4 hover:shadow-sm transition-shadow"
            >
              {/* Header: name + enabled badge */}
              <div className="flex items-start justify-between gap-2">
                <h3 className="font-semibold text-sm">{skill.name}</h3>
                <EnabledBadge enabled={skill.enabled} />
              </div>

              {/* Description */}
              <p className="text-xs text-muted-foreground line-clamp-2 mt-1">
                {skill.description || 'No description'}
              </p>

              {/* Category badge */}
              <div className="mt-2">
                <CategoryBadge category={skill.category} />
              </div>

              {/* Tags */}
              {skill.tags && skill.tags.length > 0 && (
                <div className="flex flex-wrap gap-1 mt-2">
                  {skill.tags.map((tag) => (
                    <span
                      key={tag}
                      className="px-2 py-0.5 text-xs rounded-full bg-muted"
                    >
                      {tag}
                    </span>
                  ))}
                </div>
              )}

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

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

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