'use client';

import { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import { useApi } from '@/lib/useApi';
import { SetPageHeader } from '@/components/layout/SetPageHeader';
import { listStores, createStore, updateStore, deactivateStore } from '@/services/stores';
import type { z } from 'zod/v4';
import type { StoreResponseSchema } from '@meshitrack/shared';

type Store = z.infer<typeof StoreResponseSchema>;

const PRESET_TAGS = ['pharmacy', 'grocery', 'online', 'bulk', 'discount'];

const TAG_PILL: Record<string, string> = {
  pharmacy: 'mt-pill--info',
  grocery: 'mt-pill--ok',
  online: 'mt-pill--brand',
  bulk: 'mt-pill--warn',
  discount: 'mt-pill--warn',
};

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString();
}

// --- Store form ---

function StoreForm({
  initial,
  onSaved,
  onCancel,
  householdId,
}: {
  initial?: Store;
  onSaved: () => void;
  onCancel: () => void;
  householdId: string;
}) {
  const [name, setName] = useState(initial?.name ?? '');
  const [address, setAddress] = useState(initial?.address ?? '');
  const [url, setUrl] = useState(initial?.url ?? '');
  const [notes, setNotes] = useState(initial?.notes ?? '');
  const [tags, setTags] = useState<string[]>(initial?.tags ?? []);
  const [customTag, setCustomTag] = useState('');
  const [isActive, setIsActive] = useState(initial?.isActive ?? true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState('');

  function toggleTag(tag: string) {
    setTags((prev) => (prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]));
  }

  function addCustomTag() {
    const t = customTag.trim().toLowerCase();
    if (t && !tags.includes(t)) setTags((prev) => [...prev, t]);
    setCustomTag('');
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError('');
    setSubmitting(true);
    try {
      const data = {
        name: name.trim(),
        address: address.trim() || undefined,
        url: url.trim() || undefined,
        notes: notes.trim() || undefined,
        tags,
        isActive,
      };
      if (initial) {
        await updateStore(householdId, initial._id, data);
      } else {
        await createStore(householdId, data);
      }
      onSaved();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save store');
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="mt-card mb-6">
      <h2 className="text-lg font-semibold mb-4">{initial ? 'Edit Store' : 'Add Store'}</h2>
      {error && <div className="mt-alert mt-alert--danger mb-4">{error}</div>}
      <form onSubmit={handleSubmit} className="space-y-4">
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Name</label>
            <input
              type="text"
              required
              maxLength={200}
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="e.g. Walgreens"
              className="mt-field"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Address (optional)
            </label>
            <input
              type="text"
              maxLength={500}
              value={address}
              onChange={(e) => setAddress(e.target.value)}
              placeholder="123 Main St"
              className="mt-field"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Website (optional)
            </label>
            <input
              type="url"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              placeholder="https://walgreens.com"
              className="mt-field"
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Notes (optional)</label>
            <input
              type="text"
              maxLength={1000}
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              placeholder="Any notes"
              className="mt-field"
            />
          </div>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">Tags</label>
          <div className="flex flex-wrap gap-2 mb-2">
            {PRESET_TAGS.map((tag) => (
              <button
                key={tag}
                type="button"
                onClick={() => toggleTag(tag)}
                className={`rounded-full px-3 py-1 text-xs font-medium border transition-colors ${
                  tags.includes(tag)
                    ? (TAG_PILL[tag] ? `mt-pill ${TAG_PILL[tag]}` : 'bg-gray-200 text-gray-800') +
                      ' border-transparent'
                    : 'bg-white text-gray-600 border-gray-300 hover:bg-gray-50'
                }`}
              >
                {tag}
              </button>
            ))}
          </div>
          {tags.filter((t) => !PRESET_TAGS.includes(t)).length > 0 && (
            <div className="flex flex-wrap gap-2 mb-2">
              {tags
                .filter((t) => !PRESET_TAGS.includes(t))
                .map((tag) => (
                  <span
                    key={tag}
                    className="inline-flex items-center gap-1 rounded-full bg-gray-100 px-3 py-1 text-xs text-gray-700"
                  >
                    {tag}
                    <button
                      type="button"
                      onClick={() => setTags((prev) => prev.filter((t) => t !== tag))}
                      className="text-gray-400 hover:text-red-500"
                    >
                      &times;
                    </button>
                  </span>
                ))}
            </div>
          )}
          <div className="flex gap-2">
            <input
              type="text"
              value={customTag}
              onChange={(e) => setCustomTag(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                  addCustomTag();
                }
              }}
              placeholder="Custom tag..."
              maxLength={50}
              className="mt-field"
              style={{ width: 'auto' }}
            />
            <button type="button" onClick={addCustomTag} className="mt-btn mt-btn--ghost">
              Add
            </button>
          </div>
        </div>

        {initial && (
          <div className="flex items-center gap-3">
            <input
              type="checkbox"
              id="isActive"
              checked={isActive}
              onChange={(e) => setIsActive(e.target.checked)}
              className="h-4 w-4 rounded border-gray-300"
            />
            <label htmlFor="isActive" className="text-sm font-medium text-gray-700">
              Active
            </label>
          </div>
        )}

        <div className="flex gap-3 pt-2">
          <button type="submit" disabled={submitting} className="mt-btn mt-btn--primary">
            {submitting ? 'Saving...' : initial ? 'Save changes' : 'Add Store'}
          </button>
          <button type="button" onClick={onCancel} className="mt-btn mt-btn--ghost">
            Cancel
          </button>
        </div>
      </form>
    </div>
  );
}

// --- Store card ---

function StoreCard({
  store,
  onEdit,
  onDeactivate,
}: {
  store: Store;
  onEdit: (store: Store) => void;
  onDeactivate: (store: Store) => void;
}) {
  return (
    <div className={`mt-card ${!store.isActive ? 'opacity-60' : ''}`}>
      <div className="flex items-start justify-between gap-4">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 flex-wrap mb-1">
            <h3 className="font-semibold text-gray-900">{store.name}</h3>
            {!store.isActive && <span className="mt-pill mt-pill--ghost">Inactive</span>}
          </div>
          {store.address && <p className="text-sm text-gray-500 mb-1">{store.address}</p>}
          {store.url && (
            <a
              href={store.url}
              target="_blank"
              rel="noreferrer"
              className="mt-link text-xs block mb-1"
            >
              {store.url}
            </a>
          )}
          {store.notes && <p className="text-xs text-gray-400 mb-1">{store.notes}</p>}
          {store.tags.length > 0 && (
            <div className="flex flex-wrap gap-1 mt-1">
              {store.tags.map((tag) => (
                <span key={tag} className={`mt-pill ${TAG_PILL[tag] ?? 'mt-pill--ghost'}`}>
                  {tag}
                </span>
              ))}
            </div>
          )}
          <p className="text-xs text-gray-400 mt-2">Added {formatDate(store.createdAt)}</p>
        </div>
        <div className="flex items-center gap-1 shrink-0">
          <button onClick={() => onEdit(store)} className="mt-btn mt-btn--icon" title="Edit">
            <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
              />
            </svg>
          </button>
          {store.isActive && (
            <button
              onClick={() => onDeactivate(store)}
              className="mt-btn mt-btn--danger-icon"
              title="Deactivate"
            >
              <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"
                />
              </svg>
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

// --- Main page ---

function StoresContent({ householdId }: { householdId: string }) {
  const [stores, setStores] = useState<Store[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [showForm, setShowForm] = useState(false);
  const [editingStore, setEditingStore] = useState<Store | null>(null);
  const [search, setSearch] = useState('');
  const [filterTag, setFilterTag] = useState('');
  const [showInactive, setShowInactive] = useState(false);

  const fetchStores = useCallback(async () => {
    setLoading(true);
    try {
      const result = await listStores(householdId, {
        search: search || undefined,
        tags: filterTag || undefined,
        limit: 50,
      });
      setStores(result.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load stores');
    } finally {
      setLoading(false);
    }
  }, [householdId, search, filterTag]);

  useEffect(() => {
    fetchStores();
  }, [fetchStores]);

  async function handleDeactivate(store: Store) {
    if (!confirm(`Deactivate "${store.name}"?`)) return;
    try {
      await deactivateStore(householdId, store._id);
      fetchStores();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to deactivate store');
    }
  }

  const visible = showInactive ? stores : stores.filter((s) => s.isActive);

  return (
    <div>
      <div className="flex items-center justify-between mb-4">
        <h1 className="text-2xl font-bold">Stores</h1>
        <button
          onClick={() => {
            setEditingStore(null);
            setShowForm(!showForm);
          }}
          className="mt-btn mt-btn--primary"
        >
          {showForm ? 'Cancel' : 'Add Store'}
        </button>
      </div>

      {error && (
        <div className="mt-alert mt-alert--danger mb-4">
          {error}
          <button onClick={() => setError('')} className="ml-2 underline">
            Dismiss
          </button>
        </div>
      )}

      {showForm && !editingStore && (
        <StoreForm
          householdId={householdId}
          onSaved={() => {
            setShowForm(false);
            fetchStores();
          }}
          onCancel={() => setShowForm(false)}
        />
      )}

      {editingStore && (
        <StoreForm
          householdId={householdId}
          initial={editingStore}
          onSaved={() => {
            setEditingStore(null);
            fetchStores();
          }}
          onCancel={() => setEditingStore(null)}
        />
      )}

      <div className="mb-4 flex flex-wrap items-center gap-3">
        <input
          type="text"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Search stores..."
          className="mt-field max-w-xs"
        />
        <select
          value={filterTag}
          onChange={(e) => setFilterTag(e.target.value)}
          className="mt-field"
          style={{ width: 'auto' }}
        >
          <option value="">All tags</option>
          {PRESET_TAGS.map((tag) => (
            <option key={tag} value={tag}>
              {tag}
            </option>
          ))}
        </select>
        <label className="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={(e) => setShowInactive(e.target.checked)}
            className="h-4 w-4 rounded border-gray-300"
          />
          Show inactive
        </label>
      </div>

      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 3 }).map((_, i) => (
            <div key={i} className="animate-pulse rounded-xl border bg-white p-4 h-20" />
          ))}
        </div>
      ) : visible.length === 0 ? (
        <div className="mt-card text-center" style={{ color: 'var(--ink-muted)' }}>
          {search || filterTag
            ? 'No stores match your filters.'
            : 'No stores yet. Add your first one above.'}
        </div>
      ) : (
        <div className="space-y-3">
          {visible.map((store) => (
            <StoreCard
              key={store._id}
              store={store}
              onEdit={(s) => {
                setShowForm(false);
                setEditingStore(s);
              }}
              onDeactivate={handleDeactivate}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export default function StoresPage() {
  const { householdId, isLoading: sessionLoading } = useApi();

  if (sessionLoading) {
    return (
      <>
        <SetPageHeader title="Stores" subtitle="Pharmacies and vendors" />
        <div style={{ padding: '28px 32px' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {[1, 2, 3].map((i) => (
              <div
                key={i}
                style={{ height: 64, borderRadius: 'var(--r-md)', background: 'var(--bg-inset)' }}
              />
            ))}
          </div>
        </div>
      </>
    );
  }

  if (!householdId) {
    return (
      <>
        <SetPageHeader title="Stores" subtitle="Pharmacies and vendors" />
        <div style={{ padding: '28px 32px' }}>
          <div
            style={{
              background: 'var(--bg-elev)',
              border: '1px solid var(--border)',
              borderRadius: 'var(--r-md)',
              padding: 24,
            }}
          >
            <p style={{ color: 'var(--ink-muted)', fontSize: 14 }}>
              You need to{' '}
              <Link href="/settings" style={{ color: 'var(--brand)', textDecoration: 'underline' }}>
                create or join a household
              </Link>{' '}
              before managing stores.
            </p>
          </div>
        </div>
      </>
    );
  }

  return (
    <>
      <SetPageHeader title="Stores" subtitle="Pharmacies and vendors" />
      <div className="mt-page">
        <StoresContent householdId={householdId} />
      </div>
    </>
  );
}
