'use client';

import { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import type { Recipe } from '../../features/inventory/types';

const DAYS_SV = ['Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag', 'Söndag'];

type MealPlanEntry = {
  id: number;
  date: string;
  servings: number | null;
  recipe: Pick<Recipe, 'id' | 'name' | 'imageUrl'> & {
    servings: number | null;
    ingredients: { quantity: string; unit: string; note: string | null; product: { id: number; name: string; canonicalName: string | null } }[];
  };
};

type ShoppingItem = { productId: number; name: string; quantity: number; unit: string };

type InventoryCompareItem = {
  productId: number;
  name: string;
  required: number;
  unit: string;
  available: number;
  missing: number;
  status: 'enough' | 'missing';
};

function getWeekDates(offset = 0): string[] {
  const now = new Date();
  const day = now.getDay();
  const monday = new Date(now);
  monday.setDate(now.getDate() - (day === 0 ? 6 : day - 1) + offset * 7);
  return Array.from({ length: 7 }, (_, i) => {
    const d = new Date(monday);
    d.setDate(monday.getDate() + i);
    return d.toISOString().slice(0, 10);
  });
}

export default function MealPlanClient({ recipes }: { recipes: Recipe[] }) {
  const [weekOffset, setWeekOffset] = useState(0);
  const [entries, setEntries] = useState<MealPlanEntry[]>([]);
  const [shopping, setShopping] = useState<ShoppingItem[]>([]);
  const [inventoryCompare, setInventoryCompare] = useState<InventoryCompareItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState<string | null>(null); // date being saved

  const weekDates = getWeekDates(weekOffset);
  const from = weekDates[0];
  const to = weekDates[6];

  const weekLabel = (() => {
    const f = new Date(from);
    const t = new Date(to);
    return `${f.toLocaleDateString('sv-SE', { day: 'numeric', month: 'short' })} – ${t.toLocaleDateString('sv-SE', { day: 'numeric', month: 'short', year: 'numeric' })}`;
  })();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [entriesRes, shoppingRes, compareRes] = await Promise.all([
        fetch(`/api/meal-plan-proxy?from=${from}&to=${to}`),
        fetch(`/api/meal-plan-proxy/shopping?from=${from}&to=${to}`),
        fetch(`/api/meal-plan-proxy/inventory-compare?from=${from}&to=${to}`),
      ]);
      const entriesData = await entriesRes.json();
      setEntries(Array.isArray(entriesData) ? entriesData : []);
      if (shoppingRes.ok) setShopping(await shoppingRes.json());
      else setShopping([]);
      if (compareRes.ok) setInventoryCompare(await compareRes.json());
      else setInventoryCompare([]);
    } catch {
      setEntries([]);
      setShopping([]);
      setInventoryCompare([]);
    } finally {
      setLoading(false);
    }
  }, [from, to]);

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

  const entryForDate = (date: string) => entries.find((e) => e.date.slice(0, 10) === date);

  const handleSelect = async (date: string, recipeId: string) => {
    setSaving(date);
    try {
      if (!recipeId) {
        await fetch(`/api/meal-plan-proxy?date=${date}`, { method: 'DELETE' });
      } else {
        const existing = entryForDate(date);
        await fetch('/api/meal-plan-proxy', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ date, recipeId: Number(recipeId), servings: existing?.servings ?? null }),
        });
      }
      await load();
    } finally {
      setSaving(null);
    }
  };

  const plannedCount = weekDates.filter((d) => entryForDate(d)).length;

  const handleServingsChange = async (date: string, servings: number | null) => {
    const entry = entryForDate(date);
    if (!entry) return;
    await fetch('/api/meal-plan-proxy', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ date, recipeId: entry.recipe.id, servings }),
    });
    await load();
  };

  return (
    <div>
      {/* Veckonavigering */}
      <div style={{ display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1.5rem' }}>
        <button onClick={() => setWeekOffset((w) => w - 1)} style={btnStyle()}>← Förra veckan</button>
        <span style={{ fontWeight: 600 }}>{weekLabel}</span>
        <button onClick={() => setWeekOffset((w) => w + 1)} style={btnStyle()}>Nästa vecka →</button>
        {weekOffset !== 0 && (
          <button onClick={() => setWeekOffset(0)} style={btnStyle('#0070f3')}>Denna vecka</button>
        )}
      </div>

      {loading ? (
        <p style={{ color: '#888' }}>Laddar...</p>
      ) : (
        <>
          {/* Veckovy */}
          <div style={{ display: 'grid', gap: '0.75rem', marginBottom: '2rem' }}>
            {weekDates.map((date, i) => {
              const entry = entryForDate(date);
              const isSaving = saving === date;
              const isToday = date === new Date().toISOString().slice(0, 10);
              return (
                <div
                  key={date}
                  style={{
                    display: 'grid',
                    gridTemplateColumns: '100px 1fr',
                    gap: '1rem',
                    alignItems: 'center',
                    padding: '0.75rem 1rem',
                    border: `1px solid ${isToday ? '#0070f3' : '#dee2e6'}`,
                    borderRadius: '8px',
                    background: isToday ? '#f0f7ff' : '#fff',
                  }}
                >
                  <div>
                    <div style={{ fontWeight: 700, fontSize: '0.9rem' }}>{DAYS_SV[i]}</div>
                    <div style={{ fontSize: '0.78rem', color: '#888' }}>
                      {new Date(date).toLocaleDateString('sv-SE', { day: 'numeric', month: 'short' })}
                    </div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', flexWrap: 'wrap' }}>
                    <select
                      value={entry?.recipe.id ?? ''}
                      onChange={(e) => handleSelect(date, e.target.value)}
                      disabled={isSaving}
                      style={{
                        flex: '1 1 200px',
                        padding: '0.5rem 0.75rem',
                        border: '1px solid #ced4da',
                        borderRadius: '6px',
                        fontSize: '0.9rem',
                        background: '#fff',
                        color: entry ? '#111' : '#888',
                      }}
                    >
                      <option value="">— Inget planerat —</option>
                      {recipes.map((r) => (
                        <option key={r.id} value={r.id}>{r.name}</option>
                      ))}
                    </select>
                    {entry && (
                      <Link
                        href={`/recipes/${entry.recipe.id}`}
                        style={{ fontSize: '0.8rem', color: '#0070f3', whiteSpace: 'nowrap' }}
                      >
                        Visa recept →
                      </Link>
                    )}
                    {entry && entry.recipe.servings && (
                      <div style={{ display: 'flex', alignItems: 'center', gap: '0.35rem', fontSize: '0.82rem', color: '#555' }}>
                        <span>Port.:</span>
                        <input
                          type="number"
                          min={1}
                          step={1}
                          value={entry.servings ?? entry.recipe.servings}
                          onChange={(e) => handleServingsChange(date, e.target.value ? Number(e.target.value) : null)}
                          style={{ width: '52px', padding: '0.25rem 0.4rem', border: '1px solid #ced4da', borderRadius: '4px', fontSize: '0.82rem' }}
                        />
                        {entry.servings && entry.servings !== entry.recipe.servings && (
                          <button
                            type="button"
                            onClick={() => handleServingsChange(date, null)}
                            title={`Återställ till ${entry.recipe.servings} portioner`}
                            style={{ fontSize: '0.75rem', color: '#888', background: 'none', border: 'none', cursor: 'pointer', padding: '0 0.2rem' }}
                          >
                            ↩ {entry.recipe.servings}
                          </button>
                        )}
                      </div>
                    )}
                    {isSaving && <span style={{ fontSize: '0.8rem', color: '#888' }}>Sparar...</span>}
                  </div>
                </div>
              );
            })}
          </div>

          {/* Inköpslista med lagerstatus */}
          <section style={{ border: '1px solid #dee2e6', borderRadius: '8px', padding: '1rem' }}>
            <h2 style={{ margin: '0 0 0.75rem', fontSize: '1.1rem' }}>
              Inköpslista ({plannedCount} {plannedCount === 1 ? 'recept' : 'recept'} planerade)
            </h2>
            {plannedCount === 0 ? (
              <p style={{ color: '#888', margin: 0 }}>Välj recept ovan för att se en samlad ingredienslista.</p>
            ) : shopping.length === 0 ? (
              <p style={{ color: '#888', margin: 0 }}>Laddar ingredienser...</p>
            ) : (() => {
                // Berika varje rad med inventariestatus
                type DisplayStatus = 'enough' | 'partial' | 'missing';
                const enriched = shopping.map((item) => {
                  const cmp = inventoryCompare.find(
                    (c) => c.productId === item.productId && c.unit === item.unit,
                  );
                  let displayStatus: DisplayStatus = 'missing';
                  let buyQty = item.quantity;
                  if (cmp) {
                    if (cmp.available >= cmp.required) {
                      displayStatus = 'enough';
                      buyQty = 0;
                    } else if (cmp.available > 0) {
                      displayStatus = 'partial';
                      buyQty = cmp.missing;
                    }
                  }
                  return { ...item, cmp, displayStatus, buyQty };
                });

                const order: Record<DisplayStatus, number> = { missing: 0, partial: 1, enough: 2 };
                enriched.sort((a, b) => order[a.displayStatus] - order[b.displayStatus] || a.name.localeCompare(b.name, 'sv'));

                const missingCount = enriched.filter((e) => e.displayStatus === 'missing').length;
                const partialCount = enriched.filter((e) => e.displayStatus === 'partial').length;
                const enoughCount  = enriched.filter((e) => e.displayStatus === 'enough').length;
                const hasCompare   = inventoryCompare.length > 0;

                const fmtQty = (n: number) => (n % 1 === 0 ? String(n) : n.toFixed(1));

                return (
                  <>
                    {/* Sammanfattning */}
                    {hasCompare && (
                      <div style={{ display: 'flex', gap: '1rem', marginBottom: '0.75rem', flexWrap: 'wrap', fontSize: '0.85rem' }}>
                        {missingCount > 0 && <span style={{ color: '#8b0000', fontWeight: 600 }}>❌ {missingCount} saknas</span>}
                        {partialCount > 0 && <span style={{ color: '#7a5000', fontWeight: 600 }}>⚠️ {partialCount} delvis hemma</span>}
                        {enoughCount  > 0 && <span style={{ color: '#1f5f2c', fontWeight: 600 }}>✅ {enoughCount} hemma</span>}
                        {missingCount === 0 && partialCount === 0 && (
                          <span style={{ color: '#1f5f2c', fontWeight: 600 }}>✅ Du har allt hemma!</span>
                        )}
                      </div>
                    )}

                    <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'grid', gap: '0.4rem' }}>
                      {enriched.map((item) => {
                        const isMissing = item.displayStatus === 'missing';
                        const isPartial = item.displayStatus === 'partial';
                        const isEnough  = item.displayStatus === 'enough';
                        const bg        = isMissing ? '#ffeaea' : isPartial ? '#fff8e6' : '#ecf8ee';
                        const icon      = isMissing ? '❌' : isPartial ? '⚠️' : '✅';

                        return (
                          <li
                            key={`${item.productId}-${item.unit}`}
                            style={{
                              display: 'grid',
                              gridTemplateColumns: hasCompare ? '1.5rem 1fr auto' : '1fr auto',
                              alignItems: 'center',
                              gap: '0.5rem',
                              padding: '0.4rem 0.6rem',
                              borderRadius: '6px',
                              background: hasCompare ? bg : 'transparent',
                              fontSize: '0.88rem',
                            }}
                          >
                            {hasCompare && <span title={isEnough ? 'Finns hemma' : isPartial ? 'Delvis hemma' : 'Saknas'}>{icon}</span>}
                            <span style={{ color: isEnough ? '#555' : '#111' }}>
                              <strong>{item.name}</strong>
                              {isPartial && item.cmp && (
                                <span style={{ color: '#7a5000', fontSize: '0.8rem', marginLeft: '0.4rem' }}>
                                  ({fmtQty(item.cmp.available)} av {fmtQty(item.cmp.required)} {item.unit} hemma)
                                </span>
                              )}
                              {isEnough && (
                                <span style={{ color: '#888', fontSize: '0.8rem', marginLeft: '0.4rem' }}>
                                  (finns hemma)
                                </span>
                              )}
                            </span>
                            <span style={{ fontWeight: 600, whiteSpace: 'nowrap', color: isEnough ? '#888' : '#111' }}>
                              {isEnough
                                ? '—'
                                : `${fmtQty(item.buyQty)} ${item.unit}`}
                            </span>
                          </li>
                        );
                      })}
                    </ul>
                  </>
                );
              })()
            }
          </section>
        </>
      )}
    </div>
  );
}

function btnStyle(bg?: string): React.CSSProperties {
  return {
    padding: '0.45rem 0.9rem',
    background: bg || '#f0f0f0',
    color: bg ? '#fff' : '#333',
    border: '1px solid ' + (bg || '#ccc'),
    borderRadius: '6px',
    cursor: 'pointer',
    fontSize: '0.9rem',
    fontWeight: 500,
  };
}
