import { useState } from 'react';
import type { FormEvent } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { createRecipe, importRecipeFromUrl } from '../services/api';
import type { RecipeDraft, UrlImportResult } from '../types/recipe';

type ImportErrorType = 'invalid-url' | 'parse-failure' | 'timeout' | 'generic';

function toTextBlock(items: string[]): string {
  return items.join('\n');
}

function toList(text: string): string[] {
  return text
    .split('\n')
    .map((line) => line.trim())
    .filter((line) => line.length > 0);
}

function getImportErrorDetails(message: string): { type: ImportErrorType; message: string } {
  const normalized = message.toLowerCase();

  if (normalized.includes('valid url')) {
    return {
      type: 'invalid-url',
      message: 'Please enter a valid URL (including https://).',
    };
  }

  if (normalized.includes('timed out')) {
    return {
      type: 'timeout',
      message: 'The import request timed out. Please try again in a moment.',
    };
  }

  if (normalized.includes('network error') || normalized.includes('could not fetch the page')) {
    return {
      type: 'generic',
      message: 'We could not reach that recipe page right now. Please try again in a moment.',
    };
  }

  if (normalized.includes('did not return an html page')) {
    return {
      type: 'generic',
      message: 'That link did not point to an HTML recipe page. Try the direct recipe URL.',
    };
  }

  return {
    type: 'generic',
    message,
  };
}

export function ImportUrlPage() {
  const navigate = useNavigate();

  const [url, setUrl] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [errorType, setErrorType] = useState<ImportErrorType | null>(null);
  const [result, setResult] = useState<UrlImportResult | null>(null);

  const [draft, setDraft] = useState<RecipeDraft | null>(null);
  const [draftError, setDraftError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);

  const handleSubmit = async (event: FormEvent) => {
    event.preventDefault();
    setLoading(true);
    setError(null);
    setErrorType(null);
    setResult(null);
    setDraft(null);
    setDraftError(null);

    try {
      const imported = await importRecipeFromUrl(url);
      setResult(imported);
      setDraft(imported.draft_recipe);

      if (!imported.draft_recipe) {
        setErrorType('parse-failure');
        setError('We could fetch this page, but could not find recipe fields to import.');
      }
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to import recipe URL';
      const details = getImportErrorDetails(message);
      setErrorType(details.type);
      setError(details.message);
    } finally {
      setLoading(false);
    }
  };

  const handleSave = async (event: FormEvent) => {
    event.preventDefault();
    if (!draft) {
      setDraftError('No draft recipe to save.');
      return;
    }

    const title = draft.title.trim();
    const ingredients = draft.ingredients.map((item) => item.trim()).filter(Boolean);
    const instructions = draft.instructions.map((item) => item.trim()).filter(Boolean);

    if (!title) {
      setDraftError('Title is required.');
      return;
    }
    if (ingredients.length === 0) {
      setDraftError('At least one ingredient is required.');
      return;
    }
    if (instructions.length === 0) {
      setDraftError('At least one instruction step is required.');
      return;
    }

    setIsSaving(true);
    setDraftError(null);

    try {
      const created = await createRecipe({
        ...draft,
        title,
        ingredients,
        instructions,
      });
      navigate(`/recipe/${created.id}`);
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Failed to save recipe';
      setDraftError(message);
      setIsSaving(false);
    }
  };

  return (
    <div className="max-w-3xl mx-auto">
      <h2 className="text-2xl font-bold text-gray-900 mb-2">Import from URL</h2>
      <p className="text-gray-600 mb-6">
        Paste a recipe URL and we&apos;ll try to fetch the page and extract recipe data.
      </p>

      <form onSubmit={handleSubmit} className="bg-white rounded-lg shadow p-6 space-y-4">
        <div>
          <label htmlFor="import-url" className="block text-sm font-medium text-gray-700 mb-2">
            Recipe URL
          </label>
          <input
            id="import-url"
            type="url"
            required
            value={url}
            onChange={(event) => setUrl(event.target.value)}
            placeholder="https://example.com/my-recipe"
            className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
          />
        </div>

        <button
          type="submit"
          disabled={loading}
          className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {loading ? 'Importing…' : 'Import URL'}
        </button>
      </form>

      {error && (
        <div
          className={`mt-4 border rounded-lg p-4 ${
            errorType === 'parse-failure'
              ? 'bg-amber-50 border-amber-200'
              : 'bg-red-50 border-red-200'
          }`}
        >
          <p className={errorType === 'parse-failure' ? 'text-amber-800' : 'text-red-800'}>
            <strong>
              {errorType === 'invalid-url' && 'Invalid URL:'}
              {errorType === 'timeout' && 'Import timed out:'}
              {errorType === 'parse-failure' && 'Parse failed:'}
              {errorType === 'generic' && 'Error:'}
            </strong>{' '}
            {error}
          </p>
        </div>
      )}

      {result && (
        <div className="mt-4 bg-white border border-gray-200 rounded-lg p-6 space-y-4">
          <div>
            <h3 className="font-semibold text-gray-900">Parsed Preview</h3>
            <p className="text-sm text-gray-600">Source: {result.source_url}</p>
            <p className="text-sm text-gray-600">JSON-LD blocks found: {result.json_ld_blocks.length}</p>
          </div>

          {draft ? (
            <form onSubmit={handleSave} className="space-y-4">
              <p className="text-sm text-gray-600">Review and edit before saving.</p>

              {draftError && (
                <div className="bg-red-50 border border-red-200 rounded-lg p-3 text-red-800 text-sm">
                  {draftError}
                </div>
              )}

              <div>
                <label htmlFor="draft-title" className="block text-sm font-medium text-gray-700 mb-1">
                  Title
                </label>
                <input
                  id="draft-title"
                  type="text"
                  required
                  value={draft.title}
                  onChange={(event) => setDraft({ ...draft, title: event.target.value })}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg"
                />
              </div>

              <div>
                <label htmlFor="draft-ingredients" className="block text-sm font-medium text-gray-700 mb-1">
                  Ingredients (one per line)
                </label>
                <textarea
                  id="draft-ingredients"
                  rows={8}
                  value={toTextBlock(draft.ingredients)}
                  onChange={(event) => setDraft({ ...draft, ingredients: toList(event.target.value) })}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg"
                />
              </div>

              <div>
                <label htmlFor="draft-instructions" className="block text-sm font-medium text-gray-700 mb-1">
                  Steps (one per line)
                </label>
                <textarea
                  id="draft-instructions"
                  rows={10}
                  value={toTextBlock(draft.instructions)}
                  onChange={(event) => setDraft({ ...draft, instructions: toList(event.target.value) })}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg"
                />
              </div>

              <div>
                <label htmlFor="draft-source-url" className="block text-sm font-medium text-gray-700 mb-1">
                  Source URL
                </label>
                <input
                  id="draft-source-url"
                  type="url"
                  value={draft.source_url ?? ''}
                  onChange={(event) =>
                    setDraft({
                      ...draft,
                      source_url: event.target.value.trim() ? event.target.value : undefined,
                    })
                  }
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg"
                />
              </div>

              <div className="flex gap-3">
                <button
                  type="submit"
                  disabled={isSaving}
                  className="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg font-medium disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  {isSaving ? 'Saving…' : 'Save Recipe'}
                </button>
                <Link
                  to="/recipe/new"
                  className="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 font-medium"
                >
                  Open full editor
                </Link>
              </div>
            </form>
          ) : (
            <p className="text-amber-700 bg-amber-50 border border-amber-200 rounded p-3 text-sm">
              Could not parse a recipe preview from this URL.
            </p>
          )}
        </div>
      )}
    </div>
  );
}
