import { Link } from 'react-router-dom';
import type { Recipe, Tag } from '../types/recipe';
import { colors, radius, shadows, typography } from '../theme';

interface PhotoManifestCategoryAsset {
  localPath?: string | null;
  remoteCandidate?: string | null;
}

interface PhotoManifest {
  assets?: {
    photos?: {
      list?: {
        default4x3?: string;
      };
      category?: Record<string, PhotoManifestCategoryAsset>;
    };
  };
}

interface RecipeCardProps {
  recipe: Recipe;
  tags?: Tag[];
  viewMode?: 'grid' | 'list';
  photoManifest?: PhotoManifest | null;
}

const DEFAULT_LIST_FALLBACK = '/assets/food/placeholder-recipe-4x3.svg';

function formatTime(minutes?: number): string {
  if (!minutes) return '';
  if (minutes < 60) return `${minutes}m`;
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
}

function formatDate(timestamp?: number | null): string {
  if (!timestamp) return '';
  const date = new Date(timestamp * 1000);
  return date.toLocaleDateString();
}

function inferDifficulty(recipe: Recipe): 'Easy' | 'Medium' | 'Advanced' {
  const totalTime = (recipe.prep_time_minutes || 0) + (recipe.cook_time_minutes || 0);
  const ingredientCount = recipe.ingredients.length;
  const stepCount = recipe.steps.length;

  const complexityScore = totalTime / 20 + ingredientCount / 5 + stepCount / 4;
  if (complexityScore < 4) return 'Easy';
  if (complexityScore < 8) return 'Medium';
  return 'Advanced';
}

function categoryForRecipe(tags: Tag[]): string {
  return tags[0]?.name ?? 'Uncategorized';
}

function getRecipeImageUrl(recipe: Recipe): string | null {
  const candidateKeys = [
    'image_url',
    'imageUrl',
    'photo_url',
    'photoUrl',
    'thumbnail_url',
    'thumbnailUrl',
    'image',
    'photo',
  ] as const;

  const recipeRecord = recipe as unknown as Record<string, unknown>;

  for (const key of candidateKeys) {
    const value = recipeRecord[key];
    if (typeof value !== 'string') continue;

    const trimmed = value.trim();
    if (!trimmed) continue;

    if (
      trimmed.startsWith('http://') ||
      trimmed.startsWith('https://') ||
      trimmed.startsWith('/') ||
      trimmed.startsWith('data:image/') ||
      trimmed.startsWith('blob:')
    ) {
      return trimmed;
    }
  }

  return null;
}

function recipeCategoryKey(recipe: Recipe, tags: Tag[]): 'breakfast' | 'dinner' | 'dessert' | null {
  const haystack = `${recipe.title} ${tags.map((tag) => tag.name).join(' ')}`.toLowerCase();

  if (haystack.includes('dessert') || haystack.includes('cake') || haystack.includes('cookie') || haystack.includes('sweet')) {
    return 'dessert';
  }

  if (haystack.includes('breakfast') || haystack.includes('toast') || haystack.includes('egg')) {
    return 'breakfast';
  }

  if (
    haystack.includes('dinner') ||
    haystack.includes('main') ||
    haystack.includes('pasta') ||
    haystack.includes('stew') ||
    haystack.includes('soup')
  ) {
    return 'dinner';
  }

  return null;
}

function listFallbackFromManifest(photoManifest?: PhotoManifest | null): string {
  return photoManifest?.assets?.photos?.list?.default4x3 || DEFAULT_LIST_FALLBACK;
}

function categoryImageFromManifest(
  key: 'breakfast' | 'dinner' | 'dessert',
  photoManifest?: PhotoManifest | null,
): string | null {
  const categoryAsset = photoManifest?.assets?.photos?.category?.[key];
  if (!categoryAsset) return null;

  if (categoryAsset.localPath && categoryAsset.localPath.trim().length > 0) {
    return categoryAsset.localPath;
  }

  if (categoryAsset.remoteCandidate && categoryAsset.remoteCandidate.trim().length > 0) {
    return categoryAsset.remoteCandidate;
  }

  return null;
}

function imageForRecipe(recipe: Recipe, tags: Tag[], photoManifest?: PhotoManifest | null): string {
  const directRecipeImage = getRecipeImageUrl(recipe);
  if (directRecipeImage) return directRecipeImage;

  const categoryKey = recipeCategoryKey(recipe, tags);
  if (categoryKey) {
    const categoryImage = categoryImageFromManifest(categoryKey, photoManifest);
    if (categoryImage) return categoryImage;
  }

  return listFallbackFromManifest(photoManifest);
}

function Badge({ label, value }: { label: string; value: string }) {
  return (
    <span className="ui-chip border-[var(--border)]/80 bg-white/90 px-2.5 py-1 text-xs font-semibold text-[var(--text)]">
      <span className="text-[var(--text-dim)]">{label}</span>
      <span>{value}</span>
    </span>
  );
}

export function RecipeCard({ recipe, tags = [], viewMode = 'grid', photoManifest = null }: RecipeCardProps) {
  const totalTime = (recipe.prep_time_minutes || 0) + (recipe.cook_time_minutes || 0);
  const difficulty = inferDifficulty(recipe);
  const category = categoryForRecipe(tags);
  const imageSrc = imageForRecipe(recipe, tags, photoManifest);
  const listFallback = listFallbackFromManifest(photoManifest);

  if (viewMode === 'list') {
    return (
      <Link
        to={`/recipe/${recipe.id}`}
        className="ui-card group grid grid-cols-1 gap-3 overflow-hidden border-[var(--border)]/85 bg-[var(--surface)]/95 p-3 outline-none transition-all duration-200 hover:border-[var(--color-primary)]/35 hover:[box-shadow:var(--shadow-hover)] md:grid-cols-[minmax(0,2.2fr)_minmax(0,1.4fr)_minmax(0,1fr)_auto] md:items-center md:gap-4 md:p-4"
        style={{ boxShadow: shadows.card, borderRadius: radius.lg }}
      >
        <div className="min-w-0 md:pr-2">
          <p className="mb-1 hidden text-[11px] font-semibold uppercase tracking-[0.08em] text-[var(--text-dim)]/85 md:block">Title</p>
          <div className="flex min-w-0 items-start gap-2.5">
            <div className="mt-0.5 hidden h-10 w-10 shrink-0 overflow-hidden rounded-md border border-[var(--border)]/70 bg-[var(--surface-muted)] lg:block">
              <img
                src={imageSrc}
                alt=""
                aria-hidden="true"
                className="h-full w-full object-cover"
                onError={(e) => {
                  e.currentTarget.src = listFallback;
                }}
              />
            </div>

            <div className="min-w-0">
              <h3
                className="line-clamp-1 text-base font-bold text-[var(--text-h)] transition-colors duration-200 group-hover:text-[var(--color-primary-dark)] sm:text-lg"
                style={{ fontSize: typography.fontSize.lg }}
              >
                {recipe.title}
              </h3>
              {recipe.description ? (
                <p className="mt-1 line-clamp-2 text-sm text-[var(--text-dim)] md:line-clamp-1">{recipe.description}</p>
              ) : (
                <p className="mt-1 text-sm italic text-[var(--text-dim)]/70">No description yet</p>
              )}
            </div>
          </div>
        </div>

        <div className="min-w-0">
          <p className="mb-1 hidden text-[11px] font-semibold uppercase tracking-[0.08em] text-[var(--text-dim)]/85 md:block">Tags</p>
          <div className="flex flex-wrap gap-1.5">
            {tags.slice(0, 3).map((tag) => (
              <span
                key={tag.id}
                className="ui-chip px-2 py-0.5 text-[11px] font-semibold text-white shadow-sm"
                style={{ backgroundColor: tag.color || colors.primary, borderRadius: radius.full }}
              >
                {tag.name}
              </span>
            ))}
            {tags.length > 3 ? (
              <span className="ui-chip bg-[var(--surface-muted)] px-2 py-0.5 text-[11px] font-medium text-[var(--text-dim)]">
                +{tags.length - 3}
              </span>
            ) : null}
            {tags.length === 0 ? <span className="text-sm text-[var(--text-dim)]/80">No tags</span> : null}
          </div>
        </div>

        <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-xs text-[var(--text-dim)] sm:text-sm md:grid-cols-1 md:gap-y-1.5">
          <p className="mb-0.5 col-span-2 hidden text-[11px] font-semibold uppercase tracking-[0.08em] text-[var(--text-dim)]/85 md:block">Details</p>
          <div>
            <span className="font-semibold text-[var(--text)]">Time:</span> {totalTime > 0 ? formatTime(totalTime) : 'Flexible'}
          </div>
          <div>
            <span className="font-semibold text-[var(--text)]">Difficulty:</span> {difficulty}
          </div>
          <div>
            <span className="font-semibold text-[var(--text)]">Category:</span> {category}
          </div>
          <div>
            <span className="font-semibold text-[var(--text)]">Last:</span> {recipe.last_cooked_at ? formatDate(recipe.last_cooked_at) : 'Never'}
          </div>
        </div>

        <div className="hidden self-center text-right text-sm font-semibold text-[var(--color-primary)] md:block">
          View →
        </div>
      </Link>
    );
  }

  return (
    <Link
      to={`/recipe/${recipe.id}`}
      className="ui-card group flex h-full flex-col overflow-hidden bg-[var(--surface)]/95 outline-none transition-all duration-200 hover:-translate-y-0.5 hover:border-[var(--color-primary)]/35 hover:[box-shadow:var(--shadow-hover)]"
      style={{ boxShadow: shadows.card, borderRadius: radius.lg }}
    >
      <div className="relative h-48 overflow-hidden border-[var(--border)] border-b">
        <img
          src={imageSrc}
          alt=""
          aria-hidden="true"
          className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
          onError={(e) => {
            e.currentTarget.src = listFallback;
          }}
        />
        <div
          className="pointer-events-none absolute inset-0"
          style={{ background: 'linear-gradient(to top, rgba(28, 25, 23, 0.45), rgba(28, 25, 23, 0.1), transparent)' }}
        />
        <div className="absolute bottom-3 left-3 right-3 flex flex-wrap gap-1.5">
          {totalTime > 0 ? <Badge label="Time" value={formatTime(totalTime)} /> : <Badge label="Time" value="Flexible" />}
          <Badge label="Category" value={category} />
          <Badge label="Difficulty" value={difficulty} />
        </div>
      </div>

      <div className="flex min-h-[220px] flex-1 flex-col p-5">
        <h3
          className="mb-2 line-clamp-2 text-lg font-bold text-[var(--text-h)] transition-colors duration-200 group-hover:text-[var(--color-primary-dark)]"
          style={{ fontSize: typography.fontSize.lg }}
        >
          {recipe.title}
        </h3>

        {recipe.description ? (
          <p className="mb-3 line-clamp-2 text-sm text-[var(--text-dim)]">{recipe.description}</p>
        ) : (
          <p className="mb-3 text-sm italic text-[var(--text-dim)]/70">No description yet</p>
        )}

        <div className="mb-3 flex flex-wrap gap-1.5">
          {tags.slice(0, 4).map((tag) => (
            <span
              key={tag.id}
              className="ui-chip px-2.5 py-1 text-xs font-semibold text-white shadow-sm"
              style={{ backgroundColor: tag.color || colors.primary, borderRadius: radius.full }}
            >
              {tag.name}
            </span>
          ))}
          {tags.length > 4 ? (
            <span className="ui-chip bg-[var(--surface-muted)] px-2 py-1 text-xs font-medium text-[var(--text-dim)]">
              +{tags.length - 4}
            </span>
          ) : null}
        </div>

        <div className="mt-auto flex items-center justify-between border-t border-[var(--border)]/70 pt-3 text-xs text-[var(--text-dim)]">
          <span>{recipe.last_cooked_at ? `Cooked ${formatDate(recipe.last_cooked_at)}` : 'Not cooked yet'}</span>
          <span className="inline-flex items-center gap-1 font-medium text-[var(--color-primary)]">
            View recipe
            <span className="transition-transform duration-200 group-hover:translate-x-0.5" aria-hidden="true">
              →
            </span>
          </span>
        </div>
      </div>
    </Link>
  );
}
