import { useEffect, useState } from "react";
import { Loader2 } from "lucide-react";

interface Service {
  id: string;
  name: string;
  description?: string;
  basePriceCents: number;
  durationMinutes: number;
  active: boolean;
}

interface BufferRule {
  id: string;
  serviceId: string;
  serviceName: string;
  sizeCategory?: string;
  coatType?: string;
  bufferMinutes: number;
  createdAt: string;
  updatedAt: string;
}

interface BufferRuleForm {
  serviceId: string;
  sizeCategory: string;
  coatType: string;
  bufferMinutes: string;
}

const EMPTY_FORM: BufferRuleForm = {
  serviceId: "",
  sizeCategory: "",
  coatType: "",
  bufferMinutes: "",
};

const SIZE_OPTIONS = ["", "small", "medium", "large", "xlarge"] as const;
const COAT_OPTIONS = ["", "smooth", "double", "wire", "curly", "long", "hairless"] as const;

export function BufferRulesSection() {
  const [rules, setRules] = useState<BufferRule[]>([]);
  const [services, setServices] = useState<Service[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState<BufferRuleForm>(EMPTY_FORM);
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editBuffer, setEditBuffer] = useState<string>("");

  useEffect(() => {
    Promise.all([
      fetch("/api/buffer-rules").then(r => r.ok ? r.json() : []),
      fetch("/api/services?includeInactive=true").then(r => r.ok ? r.json() : []),
    ]).then(([rulesData, servicesData]) => {
      setRules(rulesData as BufferRule[]);
      setServices(servicesData as Service[]);
    }).catch(() => setError("Failed to load")).finally(() => setLoading(false));
  }, []);

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    const mins = parseInt(form.bufferMinutes);
    if (!form.serviceId || isNaN(mins) || mins <= 0) {
      setFormError("Service and valid buffer minutes are required.");
      return;
    }
    setSaving(true);
    setFormError(null);
    try {
      const body: Record<string, string | number> = {
        serviceId: form.serviceId,
        bufferMinutes: mins,
      };
      if (form.sizeCategory) body.sizeCategory = form.sizeCategory;
      if (form.coatType) body.coatType = form.coatType;
      const res = await fetch("/api/buffer-rules", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({})) as { error?: string };
        throw new Error(err.error ?? `HTTP ${res.status}`);
      }
      const newRule = await res.json() as BufferRule;
      setRules(prev => [...prev, newRule]);
      setShowForm(false);
      setForm(EMPTY_FORM);
    } catch (e: unknown) {
      setFormError(e instanceof Error ? e.message : "Failed to create rule");
    } finally {
      setSaving(false);
    }
  }

  async function handleDelete(id: string) {
    setDeletingId(id);
    try {
      await fetch(`/api/buffer-rules/${id}`, { method: "DELETE" });
      setRules(prev => prev.filter(r => r.id !== id));
    } finally {
      setDeletingId(null);
      setConfirmDeleteId(null);
    }
  }

  function startEdit(rule: BufferRule) {
    setEditingId(rule.id);
    setEditBuffer(String(rule.bufferMinutes));
  }

  async function saveEdit(rule: BufferRule) {
    const mins = parseInt(editBuffer);
    if (isNaN(mins) || mins <= 0) return;
    setSaving(true);
    try {
      const res = await fetch(`/api/buffer-rules/${rule.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ bufferMinutes: mins }),
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const updated = await res.json() as BufferRule;
      setRules(prev => prev.map(r => r.id === updated.id ? updated : r));
    } catch {
      // silent fail
    } finally {
      setSaving(false);
      setEditingId(null);
      setEditBuffer("");
    }
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center py-8">
        <Loader2 size={20} className="animate-spin text-stone-400" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="py-4 text-sm text-red-500">{error}</div>
    );
  }

  return (
    <div>
      <div className="flex items-center justify-between mb-4">
        <div>
          <h2 className="text-base font-semibold text-stone-800">Buffer Rules</h2>
          <p className="text-sm text-stone-500">Extra time rules per service / pet size / coat type</p>
        </div>
        <button
          onClick={() => { setShowForm(!showForm); setFormError(null); }}
          className="px-3 py-1.5 bg-(--color-primary) text-white text-sm rounded-lg hover:bg-(--color-primary-hover)"
        >
          {showForm ? "Cancel" : "+ Add Rule"}
        </button>
      </div>

      {showForm && (
        <form onSubmit={handleCreate} className="mb-6 p-4 bg-stone-50 rounded-xl border border-stone-200 space-y-3">
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <div>
              <label className="block text-xs font-medium text-stone-600 mb-1">Service *</label>
              <select
                value={form.serviceId}
                onChange={e => setForm(f => ({ ...f, serviceId: e.target.value }))}
                required
                className="w-full border border-stone-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-(--color-accent)"
              >
                <option value="">Select service…</option>
                {services.map(s => (
                  <option key={s.id} value={s.id}>{s.name}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-xs font-medium text-stone-600 mb-1">Buffer (minutes) *</label>
              <input
                type="number"
                min="1"
                step="1"
                value={form.bufferMinutes}
                onChange={e => setForm(f => ({ ...f, bufferMinutes: e.target.value }))}
                required
                className="w-full border border-stone-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-(--color-accent)"
              />
            </div>
            <div>
              <label className="block text-xs font-medium text-stone-600 mb-1">Size Category</label>
              <select
                value={form.sizeCategory}
                onChange={e => setForm(f => ({ ...f, sizeCategory: e.target.value }))}
                className="w-full border border-stone-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-(--color-accent)"
              >
                <option value="">Any</option>
                {SIZE_OPTIONS.filter(s => s).map(s => (
                  <option key={s} value={s}>{s.charAt(0).toUpperCase() + s.slice(1)}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-xs font-medium text-stone-600 mb-1">Coat Type</label>
              <select
                value={form.coatType}
                onChange={e => setForm(f => ({ ...f, coatType: e.target.value }))}
                className="w-full border border-stone-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-(--color-accent)"
              >
                <option value="">Any</option>
                {COAT_OPTIONS.filter(c => c).map(c => (
                  <option key={c} value={c}>{c.charAt(0).toUpperCase() + c.slice(1)}</option>
                ))}
              </select>
            </div>
          </div>
          {formError && <p className="text-sm text-red-500">{formError}</p>}
          <button
            type="submit"
            disabled={saving}
            className="px-4 py-2 bg-(--color-primary) text-white text-sm rounded-lg hover:bg-(--color-primary-hover) disabled:opacity-60"
          >
            {saving ? "Saving…" : "Create Rule"}
          </button>
        </form>
      )}

      {rules.length === 0 && !showForm ? (
        <p className="text-sm text-stone-400 py-6 text-center">No buffer rules configured yet.</p>
      ) : (
        <div className="space-y-2">
          {rules.map(rule => (
            <div key={rule.id} className="flex items-center gap-3 p-3 bg-white rounded-xl border border-stone-200">
              <div className="flex-1 min-w-0">
                <div className="text-sm font-medium text-stone-800 truncate">{rule.serviceName}</div>
                <div className="text-xs text-stone-500 flex gap-2 flex-wrap">
                  {rule.sizeCategory && <span>Size: {rule.sizeCategory}</span>}
                  {rule.coatType && <span>Coat: {rule.coatType}</span>}
                </div>
              </div>
              {editingId === rule.id ? (
                <div className="flex items-center gap-2">
                  <input
                    type="number"
                    min="1"
                    value={editBuffer}
                    onChange={e => setEditBuffer(e.target.value)}
                    className="w-20 border border-stone-200 rounded px-2 py-1 text-sm"
                  />
                  <span className="text-xs text-stone-500">min</span>
                  <button onClick={() => saveEdit(rule)} disabled={saving} className="text-xs text-green-600 font-medium">Save</button>
                  <button onClick={() => setEditingId(null)} className="text-xs text-stone-500">Cancel</button>
                </div>
              ) : (
                <>
                  <span className="text-sm font-medium text-stone-700">{rule.bufferMinutes} min</span>
                  <button onClick={() => startEdit(rule)} className="text-xs text-stone-500 hover:text-stone-700 px-2">Edit</button>
                </>
              )}
              {confirmDeleteId === rule.id ? (
                <div className="flex items-center gap-2">
                  <span className="text-xs text-red-500">Delete?</span>
                  <button onClick={() => handleDelete(rule.id)} disabled={deletingId === rule.id} className="text-xs text-red-600 font-medium">Confirm</button>
                  <button onClick={() => setConfirmDeleteId(null)} className="text-xs text-stone-500">Cancel</button>
                </div>
              ) : (
                <button onClick={() => setConfirmDeleteId(rule.id)} className="text-xs text-red-400 hover:text-red-600">Delete</button>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}