'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 {
  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_PILL: Record<string, string> = {
  active: 'mt-pill--ok',
  shopping: 'mt-pill--info',
  completed: 'mt-pill--ghost',
  archived: 'mt-pill--ghost',
};

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="mt-card">
      <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="mt-field"
              style={{ width: 'auto' }}
            >
              {[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="mt-btn mt-btn--primary"
            >
              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="mt-field"
          />
          <button type="submit" disabled={generating} className="mt-btn mt-btn--primary">
            {generating ? 'Creating...' : 'Create'}
          </button>
          <button
            type="button"
            onClick={() => setShowGenerateForm(false)}
            className="mt-btn mt-btn--ghost"
          >
            Cancel
          </button>
        </form>
      )}

      {error && (
        <div className="mt-alert mt-alert--danger mb-4">
          {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="mt-card">
      <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={`mt-pill ${STATUS_PILL[list.status] ?? STATUS_PILL['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="mt-btn mt-btn--icon" 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="mt-alert mt-alert--danger mb-4">
          {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="h-4 w-4 rounded border-gray-300"
              />
              <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="mt-pill mt-pill--ok">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="mt-field"
                    style={{ width: '7rem', fontSize: '0.75rem' }}
                  />
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      <div className="flex flex-wrap items-center gap-3 border-t pt-4">
        {checkedNotAdded > 0 && (
          <button onClick={handleAddToCabinet} disabled={adding} className="mt-btn mt-btn--primary">
            {adding ? 'Adding...' : `Add ${checkedNotAdded} to Cabinet`}
          </button>
        )}
        {list.status === RefillListStatus.ACTIVE && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.SHOPPING)}
            className="mt-btn mt-btn--ghost"
          >
            Start shopping
          </button>
        )}
        {list.status === RefillListStatus.SHOPPING && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.COMPLETED)}
            className="mt-btn mt-btn--ghost"
          >
            Mark complete
          </button>
        )}
        {(list.status === RefillListStatus.ACTIVE || list.status === RefillListStatus.SHOPPING) && (
          <button
            onClick={() => handleUpdateStatus(RefillListStatus.ARCHIVED)}
            className="mt-btn mt-btn--ghost"
          >
            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="mt-card mb-4">
      <h3 className="text-base font-semibold mb-3">New Refill List</h3>
      {error && <div className="mt-alert mt-alert--danger mb-3">{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="mt-field"
        />
        <button type="submit" disabled={submitting} className="mt-btn mt-btn--primary">
          {submitting ? 'Creating...' : 'Create'}
        </button>
        <button type="button" onClick={onCancel} className="mt-btn mt-btn--ghost">
          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="mt-field"
            style={{ width: 'auto' }}
          >
            <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="mt-btn mt-btn--primary">
            {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="mt-alert mt-alert--danger mb-4">
          {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="mt-card text-center" style={{ color: 'var(--ink-muted)' }}>
          {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 mt-card text-left transition-colors ${
                  isSelected ? 'outline outline-2 outline-[var(--brand)]' : ''
                }`}
              >
                <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={`mt-pill ${STATUS_PILL[list.status] ?? STATUS_PILL['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>
      <div className="space-y-6">
        <AlertsPanel householdId={householdId} onGenerateList={() => setListsKey((k) => k + 1)} />
        <div className="mt-card">
          <RefillListsPanel key={listsKey} householdId={householdId} />
        </div>
      </div>
    </div>
  );
}

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

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

  if (!householdId) {
    return (
      <>
        <SetPageHeader title="Refills" subtitle="Running-low alerts and shopping lists" />
        <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 refills.
            </p>
          </div>
        </div>
      </>
    );
  }

  return (
    <>
      <SetPageHeader title="Refills" subtitle="Running-low alerts and shopping lists" />
      <div className="mt-page">
        <RefillsContent householdId={householdId} />
      </div>
    </>
  );
}
