'use client';

import { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import { useApi } from '@/lib/useApi';
import {
  getRefillAlerts,
  listRefillLists,
  createRefillList,
  updateRefillList,
  updateRefillListItem,
  addToCabinet,
} from '@/services/refills';
import { RefillListStatus } from '@meshitrack/shared';
import type { z } from 'zod/v4';
import type { RefillAlertResponseSchema, RefillListResponseSchema } from '@meshitrack/shared';

type RefillAlert = z.infer<typeof RefillAlertResponseSchema>;
type RefillList = z.infer<typeof RefillListResponseSchema>;
type RefillListItem = RefillList['items'][number];

const STATUS_LABELS: Record<string, string> = {
  active: 'Active',
  shopping: 'Shopping',
  completed: 'Completed',
  archived: 'Archived',
};

const STATUS_COLORS: Record<string, string> = {
  active: 'bg-green-100 text-green-700',
  shopping: 'bg-blue-100 text-blue-700',
  completed: 'bg-gray-100 text-gray-600',
  archived: 'bg-gray-100 text-gray-400',
};

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

// --- Refill alerts panel ---

function AlertsPanel({
  householdId,
  onGenerateList,
}: {
  householdId: string;
  onGenerateList: () => void;
}) {
  const [alerts, setAlerts] = useState<RefillAlert[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [thresholdDays, setThresholdDays] = useState(7);
  const [generating, setGenerating] = useState(false);
  const [listName, setListName] = useState('');
  const [showGenerateForm, setShowGenerateForm] = useState(false);

  const fetchAlerts = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const result = await getRefillAlerts(householdId, { thresholdDays });
      setAlerts(result.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load alerts');
    } finally {
      setLoading(false);
    }
  }, [householdId, thresholdDays]);

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

  async function handleGenerateList(e: React.FormEvent) {
    e.preventDefault();
    if (!listName.trim()) return;
    setGenerating(true);
    setError('');
    try {
      await createRefillList(householdId, {
        name: listName.trim(),
        fromAlerts: true,
        thresholdDays,
      });
      setShowGenerateForm(false);
      setListName('');
      onGenerateList();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to generate list');
    } finally {
      setGenerating(false);
    }
  }

  return (
    <div className="rounded-xl border bg-white p-6 shadow-sm">
      <div className="flex items-center justify-between mb-4 flex-wrap gap-3">
        <h2 className="text-lg font-semibold">Refill Alerts</h2>
        <div className="flex items-center gap-3">
          <div className="flex items-center gap-2 text-sm text-gray-600">
            <span>Threshold:</span>
            <select
              value={thresholdDays}
              onChange={(e) => setThresholdDays(Number(e.target.value))}
              className="rounded-lg border px-2 py-1 text-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none"
            >
              {[3, 5, 7, 10, 14, 30].map((d) => (
                <option key={d} value={d}>
                  {d} days
                </option>
              ))}
            </select>
          </div>
          {alerts.length > 0 && (
            <button
              onClick={() => setShowGenerateForm(!showGenerateForm)}
              className="rounded-lg bg-primary-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-primary-700 transition-colors"
            >
              Generate Refill List
            </button>
          )}
        </div>
      </div>

      {showGenerateForm && (
        <form onSubmit={handleGenerateList} className="mb-4 flex items-center gap-3">
          <input
            type="text"
            required
            maxLength={200}
            value={listName}
            onChange={(e) => setListName(e.target.value)}
            placeholder="List name, e.g. Weekly refills"
            className="flex-1 rounded-lg border px-3 py-2 text-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none"
          />
          <button
            type="submit"
            disabled={generating}
            className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-700 disabled:opacity-50 transition-colors"
          >
            {generating ? 'Creating...' : 'Create'}
          </button>
          <button
            type="button"
            onClick={() => setShowGenerateForm(false)}
            className="rounded-lg border px-3 py-2 text-sm font-medium hover:bg-gray-50 transition-colors"
          >
            Cancel
          </button>
        </form>
      )}

      {error && (
        <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-700">
          {error}
          <button onClick={() => setError('')} className="ml-2 underline">
            Dismiss
          </button>
        </div>
      )}

      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 2 }).map((_, i) => (
            <div key={i} className="animate-pulse h-20 rounded-lg bg-gray-200" />
          ))}
        </div>
      ) : alerts.length === 0 ? (
        <div className="py-6 text-center text-sm text-gray-500">
          No medicines running low within {thresholdDays} days.
          {thresholdDays < 30 && (
            <span className="block mt-1 text-xs">
              Try increasing the threshold to see more.
            </span>
          )}
        </div>
      ) : (
        <div className="space-y-3">
          {alerts.map((alert) => {
            const daysColor =
              alert.daysUntilEmpty <= 3
                ? 'text-red-600 font-bold'
                : alert.daysUntilEmpty <= 7
                  ? 'text-red-500 font-semibold'
                  : 'text-yellow-600';

            return (
              <div
                key={alert.medicineId}
                className="rounded-lg border bg-gray-50 p-4"
              >
                <div className="flex items-start justify-between gap-4 flex-wrap">
                  <div>
                    <h3 className="font-semibold text-gray-900">
                      {alert.medicineName}
                      <span className="ml-2 text-sm font-normal text-gray-500">
                        {alert.medicineStrength} {alert.medicineStrengthUnit}
                      </span>
                    </h3>
                    <div className="flex flex-wrap gap-4 mt-1 text-sm">
                      <span className={daysColor}>
                        {alert.daysUntilEmpty} day{alert.daysUntilEmpty !== 1 ? 's' : ''} left
                      </span>
                      <span className="text-gray-500">
                        {alert.currentStock} in cabinet
                      </span>
                      <span className="text-gray-500">
                        {alert.dailyConsumption.toFixed(2)}/day
                      </span>
                    </div>
                  </div>
                  <div className="text-right text-sm">
                    <p className="text-gray-600">
                      Suggested: <span className="font-medium">{alert.suggestedQuantity} units</span>
                    </p>
                    {alert.cheapestOption && (
                      <p className="text-green-700 font-medium">
                        Best: {alert.cheapestOption.storeName} —{' '}
                        {alert.cheapestOption.price.toFixed(2)}
                      </p>
                    )}
                    {!alert.cheapestOption && alert.lastKnownPrice && (
                      <p className="text-gray-500">
                        Last: {alert.lastKnownPrice.storeName} —{' '}
                        {alert.lastKnownPrice.price.toFixed(2)}
                      </p>
                    )}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// --- Refill list detail ---

function RefillListDetail({
  list,
  householdId,
  onUpdated,
  onClose,
}: {
  list: RefillList;
  householdId: string;
  onUpdated: () => void;
  onClose: () => void;
}) {
  const [items, setItems] = useState<RefillListItem[]>(list.items);
  const [actualPrices, setActualPrices] = useState<Record<string, string>>({});
  const [adding, setAdding] = useState(false);
  const [error, setError] = useState('');

  async function handleToggleItem(item: RefillListItem) {
    setError('');
    try {
      const updated = await updateRefillListItem(householdId, list._id, item._id, {
        checked: !item.checked,
        actualPrice:
          !item.checked && actualPrices[item._id]
            ? Number(actualPrices[item._id])
            : undefined,
      });
      setItems(updated.items);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to update item');
    }
  }

  async function handleUpdateStatus(status: RefillListStatus) {
    setError('');
    try {
      await updateRefillList(householdId, list._id, { status });
      onUpdated();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to update status');
    }
  }

  async function handleAddToCabinet() {
    const checkedCount = items.filter((i) => i.checked && !i.addedToCabinet).length;
    /* v8 ignore next 4 */
    if (checkedCount === 0) {
      setError('No checked items to add to cabinet.');
      return;
    }
    if (!confirm(`Add ${checkedCount} checked item${checkedCount !== 1 ? 's' : ''} to your cabinet?`)) return;
    setAdding(true);
    setError('');
    try {
      const result = await addToCabinet(householdId, list._id);
      onUpdated();
      setAdding(false);
      if (result.addedCount > 0) {
        alert(`Added ${result.addedCount} item${result.addedCount !== 1 ? 's' : ''} to your cabinet.`);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to add to cabinet');
      setAdding(false);
    }
  }

  const checkedNotAdded = items.filter((i) => i.checked && !i.addedToCabinet).length;
  const totalChecked = items.filter((i) => i.checked).length;

  return (
    <div className="rounded-xl border bg-white p-6 shadow-sm">
      <div className="flex items-start justify-between gap-4 mb-4">
        <div>
          <h2 className="text-lg font-semibold text-gray-900">{list.name}</h2>
          <div className="flex items-center gap-2 mt-1">
            <span className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${STATUS_COLORS[list.status] ?? STATUS_COLORS['active']}`}>
              {STATUS_LABELS[list.status] ?? list.status}
            </span>
            <span className="text-xs text-gray-400">
              {totalChecked}/{items.length} checked
            </span>
            {list.totalEstimatedCost != null && (
              <span className="text-xs text-gray-500">
                Est. {list.totalEstimatedCost.toFixed(2)}
              </span>
            )}
          </div>
        </div>
        <button
          onClick={onClose}
          className="rounded p-1 text-gray-400 hover:text-gray-600 transition-colors"
          title="Close"
        >
          <svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>

      {error && (
        <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-700">
          {error}
          <button onClick={() => setError('')} className="ml-2 underline">Dismiss</button>
        </div>
      )}

      {items.length === 0 ? (
        <p className="text-sm text-gray-500 py-4 text-center">No items in this list.</p>
      ) : (
        <div className="space-y-2 mb-4">
          {items.map((item) => (
            <div
              key={item._id}
              className={`rounded-lg border p-3 flex items-start gap-3 ${item.addedToCabinet ? 'opacity-50' : ''}`}
            >
              <input
                type="checkbox"
                checked={item.checked}
                onChange={() => handleToggleItem(item)}
                disabled={item.addedToCabinet}
                className="mt-0.5 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
              />
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 flex-wrap">
                  <span className={`text-sm font-medium ${item.checked ? 'line-through text-gray-400' : 'text-gray-900'}`}>
                    {item.medicineName}
                  </span>
                  <span className="text-xs text-gray-500">
                    {item.quantity} {item.unit}
                  </span>
                  {item.estimatedPrice != null && (
                    <span className="text-xs text-gray-400">est. {item.estimatedPrice.toFixed(2)}</span>
                  )}
                  {item.addedToCabinet && (
                    <span className="rounded-full bg-green-100 text-green-700 px-2 py-0.5 text-xs">
                      in cabinet
                    </span>
                  )}
                </div>
                {item.notes && <p className="text-xs text-gray-400 mt-0.5">{item.notes}</p>}
              </div>
              {item.checked && !item.addedToCabinet && (
                <div className="shrink-0">
                  <input
                    type="number"
                    min={0}
                    step="any"
                    value={actualPrices[item._id] ?? ''}
                    onChange={(e) =>
                      setActualPrices((prev) => ({ ...prev, [item._id]: e.target.value }))
                    }
                    placeholder="Actual price"
                    className="w-28 rounded-lg border px-2 py-1 text-xs focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none"
                  />
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      <div className="flex flex-wrap items-center gap-3 border-t pt-4">
        {checkedNotAdded > 0 && (
          <button
            onClick={handleAddToCabinet}
            disabled={adding}
            className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-700 disabled:opacity-50 transition-colors"
          >
            {adding ? 'Adding...' : `Add ${checkedNotAdded} to Cabinet`}
          </button>
        )}
        {list.status === RefillListStatus.ACTIVE && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.SHOPPING)}
            className="rounded-lg border px-3 py-2 text-sm font-medium hover:bg-gray-50 transition-colors"
          >
            Start shopping
          </button>
        )}
        {list.status === RefillListStatus.SHOPPING && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.COMPLETED)}
            className="rounded-lg border px-3 py-2 text-sm font-medium hover:bg-gray-50 transition-colors"
          >
            Mark complete
          </button>
        )}
        {(list.status === RefillListStatus.ACTIVE ||
          list.status === RefillListStatus.SHOPPING) && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.ARCHIVED)}
            className="rounded-lg border px-3 py-2 text-sm text-gray-500 hover:bg-gray-50 transition-colors"
          >
            Archive
          </button>
        )}
      </div>
    </div>
  );
}

// --- Create list form ---

function CreateListForm({
  householdId,
  onCreated,
  onCancel,
}: {
  householdId: string;
  onCreated: () => void;
  onCancel: () => void;
}) {
  const [name, setName] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState('');

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError('');
    setSubmitting(true);
    try {
      await createRefillList(householdId, { name: name.trim(), fromAlerts: false, thresholdDays: 7 });
      onCreated();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to create list');
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="mb-4 rounded-xl border bg-white p-6 shadow-sm">
      <h3 className="text-base font-semibold mb-3">New Refill List</h3>
      {error && (
        <div className="mb-3 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-700">
          {error}
        </div>
      )}
      <form onSubmit={handleSubmit} className="flex items-center gap-3">
        <input
          type="text"
          required
          maxLength={200}
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="List name"
          className="flex-1 rounded-lg border px-3 py-2 text-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none"
        />
        <button
          type="submit"
          disabled={submitting}
          className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-700 disabled:opacity-50 transition-colors"
        >
          {submitting ? 'Creating...' : 'Create'}
        </button>
        <button
          type="button"
          onClick={onCancel}
          className="rounded-lg border px-3 py-2 text-sm font-medium hover:bg-gray-50 transition-colors"
        >
          Cancel
        </button>
      </form>
    </div>
  );
}

// --- Refill lists panel ---

function RefillListsPanel({ householdId }: { householdId: string }) {
  const [lists, setLists] = useState<RefillList[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [filterStatus, setFilterStatus] = useState('');
  const [showForm, setShowForm] = useState(false);
  const [selectedList, setSelectedList] = useState<RefillList | null>(null);

  const fetchLists = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const result = await listRefillLists(householdId, {
        status: (filterStatus as RefillListStatus) || undefined,
        limit: 30,
      });
      setLists(result.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load refill lists');
    } finally {
      setLoading(false);
    }
  }, [householdId, filterStatus]);

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

  function handleSelectList(list: RefillList) {
    setSelectedList((prev) => (prev?._id === list._id ? null : list));
  }

  return (
    <div>
      <div className="flex items-center justify-between mb-4 flex-wrap gap-3">
        <h2 className="text-lg font-semibold">Refill Lists</h2>
        <div className="flex items-center gap-3">
          <select
            value={filterStatus}
            onChange={(e) => setFilterStatus(e.target.value)}
            className="rounded-lg border px-3 py-2 text-sm focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none"
          >
            <option value="">All statuses</option>
            {Object.values(RefillListStatus).map((s) => (
              <option key={s} value={s}>
                {STATUS_LABELS[s] ?? s}
              </option>
            ))}
          </select>
          <button
            onClick={() => setShowForm(!showForm)}
            className="rounded-lg bg-primary-600 px-3 py-2 text-sm font-medium text-white hover:bg-primary-700 transition-colors"
          >
            {showForm ? 'Cancel' : 'New List'}
          </button>
        </div>
      </div>

      {showForm && (
        <CreateListForm
          householdId={householdId}
          onCreated={() => {
            setShowForm(false);
            fetchLists();
          }}
          onCancel={() => setShowForm(false)}
        />
      )}

      {selectedList && (
        <div className="mb-4">
          <RefillListDetail
            key={selectedList._id}
            list={selectedList}
            householdId={householdId}
            onUpdated={() => {
              fetchLists();
              setSelectedList(null);
            }}
            onClose={() => setSelectedList(null)}
          />
        </div>
      )}

      {error && (
        <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-700">
          {error}
          <button onClick={() => setError('')} className="ml-2 underline">Dismiss</button>
        </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-16" />
          ))}
        </div>
      ) : lists.length === 0 ? (
        <div className="rounded-xl border bg-white p-6 shadow-sm text-center text-sm text-gray-500">
          {filterStatus ? `No ${STATUS_LABELS[filterStatus] ?? filterStatus} lists.` : 'No refill lists yet. Create one above or generate from alerts.'}
        </div>
      ) : (
        <div className="space-y-2">
          {lists.map((list) => {
            const checkedCount = list.items.filter((i) => i.checked).length;
            const isSelected = selectedList?._id === list._id;

            return (
              <button
                key={list._id}
                onClick={() => handleSelectList(list)}
                className={`w-full rounded-xl border p-4 text-left transition-colors ${
                  isSelected
                    ? 'bg-primary-50 border-primary-300'
                    : 'bg-white hover:bg-gray-50'
                } shadow-sm`}
              >
                <div className="flex items-center justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap mb-1">
                      <span className="font-medium text-gray-900 truncate">{list.name}</span>
                      <span
                        className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${STATUS_COLORS[list.status] ?? STATUS_COLORS['active']}`}
                      >
                        {STATUS_LABELS[list.status] ?? list.status}
                      </span>
                    </div>
                    <p className="text-xs text-gray-500">
                      {list.items.length} item{list.items.length !== 1 ? 's' : ''}
                      {list.items.length > 0 && ` — ${checkedCount} checked`}
                      {list.totalEstimatedCost != null &&
                        ` — est. ${list.totalEstimatedCost.toFixed(2)}`}
                    </p>
                  </div>
                  <div className="text-xs text-gray-400 shrink-0">{formatDate(list.createdAt)}</div>
                </div>
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

// --- Main page ---

function RefillsContent({ householdId }: { householdId: string }) {
  const [listsKey, setListsKey] = useState(0);

  return (
    <div>
      <h1 className="text-2xl font-bold mb-6">Refills</h1>
      <div className="space-y-6">
        <AlertsPanel
          householdId={householdId}
          onGenerateList={() => setListsKey((k) => k + 1)}
        />
        <div className="rounded-xl border bg-white p-6 shadow-sm">
          <RefillListsPanel key={listsKey} householdId={householdId} />
        </div>
      </div>
    </div>
  );
}

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

  if (sessionLoading) {
    return (
      <div>
        <h1 className="text-2xl font-bold mb-4">Refills</h1>
        <div className="animate-pulse space-y-4">
          <div className="h-40 rounded-xl bg-gray-200" />
          <div className="h-60 rounded-xl bg-gray-200" />
        </div>
      </div>
    );
  }

  if (!householdId) {
    return (
      <div>
        <h1 className="text-2xl font-bold mb-4">Refills</h1>
        <div className="rounded-xl border bg-white p-6 shadow-sm">
          <p className="text-gray-500">
            You need to{' '}
            <Link href="/settings" className="text-primary-600 underline">
              create or join a household
            </Link>{' '}
            before managing refills.
          </p>
        </div>
      </div>
    );
  }

  return <RefillsContent householdId={householdId} />;
}
