'use client';

import { useState, useRef } from 'react';
import { X, Upload, ImagePlus, MapPin, Loader2 } from 'lucide-react';
import { apiUrl, thumbnailUrl } from '@/lib/api';
import { reverseGeocode } from '@/lib/geocode';
import LocationPicker from './LocationPicker';
import ArchivePhotoPicker from './ArchivePhotoPicker';
import dynamic from 'next/dynamic';

const JourneyMap = dynamic(() => import('./JourneyMap'), { ssr: false });

interface StopData {
    id?: string;
    title: string;
    description: string | null;
    latitude: number | null;
    longitude: number | null;
    locationName: string | null;
    arrivalDate: string | null;
    photos?: { id: string; url: string; caption: string | null; photoId: string | null }[];
}

interface JourneyStopFormProps {
    journeyId: string;
    stop?: StopData;
    onSave: (stop: unknown) => void;
    onCancel: () => void;
}

export default function JourneyStopForm({ journeyId, stop, onSave, onCancel }: JourneyStopFormProps) {
    const isEditing = !!stop?.id;
    const [title, setTitle] = useState(stop?.title || '');
    const [description, setDescription] = useState(stop?.description || '');
    const [latitude, setLatitude] = useState<number | null>(stop?.latitude ?? null);
    const [longitude, setLongitude] = useState<number | null>(stop?.longitude ?? null);
    const [locationName, setLocationName] = useState(stop?.locationName || '');
    const [arrivalDate, setArrivalDate] = useState(
        stop?.arrivalDate ? new Date(stop.arrivalDate).toISOString().split('T')[0] : ''
    );
    const [saving, setSaving] = useState(false);
    const [uploadingPhotos, setUploadingPhotos] = useState(false);
    const [showArchivePicker, setShowArchivePicker] = useState(false);
    const [geocoding, setGeocoding] = useState(false);
    const fileInputRef = useRef<HTMLInputElement>(null);

    // Local photos added during this session
    const [photos, setPhotos] = useState<{ id: string; url: string; caption: string | null; photoId: string | null }[]>(
        stop?.photos || []
    );

    const handleMapClick = async (lat: number, lng: number) => {
        setLatitude(lat);
        setLongitude(lng);
        setGeocoding(true);
        try {
            const name = await reverseGeocode(lat, lng);
            if (name) setLocationName(name);
        } finally {
            setGeocoding(false);
        }
    };

    const handleLocationSelect = (loc: string) => {
        setLocationName(loc);
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!title.trim()) return;

        setSaving(true);
        try {
            const url = isEditing
                ? apiUrl(`/api/journeys/${journeyId}/stops/${stop!.id}`)
                : apiUrl(`/api/journeys/${journeyId}/stops`);

            const res = await fetch(url, {
                method: isEditing ? 'PUT' : 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    title: title.trim(),
                    description: description.trim() || null,
                    latitude,
                    longitude,
                    locationName: locationName || null,
                    arrivalDate: arrivalDate || null,
                }),
            });

            if (!res.ok) {
                const err = await res.json();
                alert(err.error || 'Failed to save stop');
                return;
            }

            const result = await res.json();
            onSave(result);
        } catch (error) {
            console.error('Failed to save stop:', error);
            alert('Failed to save stop');
        } finally {
            setSaving(false);
        }
    };

    const handleFileUpload = async (files: FileList) => {
        if (!stop?.id) return; // Can only upload to saved stops
        setUploadingPhotos(true);
        try {
            const formData = new FormData();
            Array.from(files).forEach(f => formData.append('files', f));

            const res = await fetch(apiUrl(`/api/journeys/${journeyId}/stops/${stop.id}/photos`), {
                method: 'POST',
                body: formData,
            });

            if (res.ok) {
                const data = await res.json();
                setPhotos(prev => [...prev, ...data.photos]);
            }
        } catch (error) {
            console.error('Photo upload error:', error);
        } finally {
            setUploadingPhotos(false);
        }
    };

    const handleArchiveSelect = async (photoIds: string[]) => {
        if (!stop?.id) return;
        setShowArchivePicker(false);
        for (const photoId of photoIds) {
            try {
                const res = await fetch(apiUrl(`/api/journeys/${journeyId}/stops/${stop.id}/photos`), {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ photoId }),
                });
                if (res.ok) {
                    const photo = await res.json();
                    setPhotos(prev => [...prev, photo]);
                }
            } catch (error) {
                console.error('Archive photo add error:', error);
            }
        }
    };

    const handleDeletePhoto = async (photoId: string) => {
        if (!stop?.id) return;
        try {
            await fetch(apiUrl(`/api/journeys/${journeyId}/stops/${stop.id}/photos/${photoId}`), {
                method: 'DELETE',
            });
            setPhotos(prev => prev.filter(p => p.id !== photoId));
        } catch (error) {
            console.error('Photo delete error:', error);
        }
    };

    const mapStops = latitude != null && longitude != null
        ? [{ id: 'current', title, locationName, latitude, longitude, order: 0 }]
        : [];

    return (
        <>
            <div className="fixed inset-0 z-50 flex items-start justify-center bg-black/40 backdrop-blur-sm p-4 overflow-y-auto">
                <div className="bg-paper rounded-xl w-full max-w-lg border-2 border-foreground/10 shadow-xl my-8">
                    <div className="flex items-center justify-between p-4 border-b border-foreground/10">
                        <h2 className="font-display text-lg">
                            {isEditing ? 'Edit Stop' : 'Add Stop'}
                        </h2>
                        <button onClick={onCancel} className="text-foreground/40 hover:text-foreground">
                            <X className="w-5 h-5" />
                        </button>
                    </div>

                    <form onSubmit={handleSubmit} className="p-4 space-y-4">
                        {/* Map for pin dropping */}
                        <div>
                            <label className="block text-sm font-medium text-foreground/60 mb-1">
                                Location <span className="text-foreground/30">(click map to drop pin)</span>
                            </label>
                            <JourneyMap
                                stops={mapStops}
                                onMapClick={handleMapClick}
                                interactive
                                height="200px"
                            />
                            {geocoding && (
                                <div className="flex items-center gap-1.5 mt-1 text-xs text-foreground/40">
                                    <Loader2 className="w-3 h-3 animate-spin" />
                                    Looking up location...
                                </div>
                            )}
                        </div>

                        {/* Location search */}
                        <div>
                            <label className="block text-sm font-medium text-foreground/60 mb-1">Location Name</label>
                            <LocationPicker
                                value={locationName}
                                onChange={handleLocationSelect}
                                placeholder="Search for a place..."
                            />
                        </div>

                        {latitude != null && longitude != null && (
                            <div className="flex items-center gap-1.5 text-xs text-foreground/30">
                                <MapPin className="w-3 h-3" />
                                {latitude.toFixed(4)}, {longitude.toFixed(4)}
                            </div>
                        )}

                        <div>
                            <label className="block text-sm font-medium text-foreground/60 mb-1">Title</label>
                            <input
                                type="text"
                                value={title}
                                onChange={e => setTitle(e.target.value)}
                                placeholder="e.g. Alfama District"
                                className="w-full px-3 py-2 bg-foreground/5 rounded-lg text-sm font-serif
                                           border border-foreground/10 focus:outline-none focus:border-foreground/30"
                                required
                            />
                        </div>

                        <div>
                            <label className="block text-sm font-medium text-foreground/60 mb-1">Story</label>
                            <textarea
                                value={description}
                                onChange={e => setDescription(e.target.value)}
                                placeholder="What happened here..."
                                rows={3}
                                className="w-full px-3 py-2 bg-foreground/5 rounded-lg text-sm font-serif
                                           border border-foreground/10 focus:outline-none focus:border-foreground/30 resize-none"
                            />
                        </div>

                        <div>
                            <label className="block text-sm font-medium text-foreground/60 mb-1">Date</label>
                            <input
                                type="date"
                                value={arrivalDate}
                                onChange={e => setArrivalDate(e.target.value)}
                                className="w-full px-3 py-2 bg-foreground/5 rounded-lg text-sm
                                           border border-foreground/10 focus:outline-none focus:border-foreground/30"
                            />
                        </div>

                        {/* Photos section (only for existing stops) */}
                        {isEditing && (
                            <div>
                                <label className="block text-sm font-medium text-foreground/60 mb-2">Photos</label>
                                <div className="grid grid-cols-4 gap-1.5 mb-2">
                                    {photos.map(photo => (
                                        <div key={photo.id} className="relative aspect-square rounded-lg overflow-hidden group/photo">
                                            <img
                                                src={thumbnailUrl(photo.url, 'sm')}
                                                alt={photo.caption || ''}
                                                className="w-full h-full object-cover"
                                            />
                                            <button
                                                type="button"
                                                onClick={() => handleDeletePhoto(photo.id)}
                                                className="absolute top-0.5 right-0.5 w-5 h-5 bg-black/60 rounded-full
                                                           flex items-center justify-center opacity-0 group-hover/photo:opacity-100 transition-opacity"
                                            >
                                                <X className="w-3 h-3 text-white" />
                                            </button>
                                        </div>
                                    ))}
                                </div>

                                <div className="flex gap-2">
                                    <button
                                        type="button"
                                        onClick={() => fileInputRef.current?.click()}
                                        disabled={uploadingPhotos}
                                        className="flex items-center gap-1.5 px-3 py-1.5 bg-foreground/5 rounded-lg text-xs
                                                   text-foreground/50 hover:bg-foreground/10 transition-colors"
                                    >
                                        {uploadingPhotos ? (
                                            <Loader2 className="w-3.5 h-3.5 animate-spin" />
                                        ) : (
                                            <Upload className="w-3.5 h-3.5" />
                                        )}
                                        Upload
                                    </button>
                                    <button
                                        type="button"
                                        onClick={() => setShowArchivePicker(true)}
                                        className="flex items-center gap-1.5 px-3 py-1.5 bg-foreground/5 rounded-lg text-xs
                                                   text-foreground/50 hover:bg-foreground/10 transition-colors"
                                    >
                                        <ImagePlus className="w-3.5 h-3.5" />
                                        From Archive
                                    </button>
                                </div>

                                <input
                                    ref={fileInputRef}
                                    type="file"
                                    accept="image/*"
                                    multiple
                                    className="hidden"
                                    onChange={e => e.target.files && handleFileUpload(e.target.files)}
                                />
                            </div>
                        )}

                        <div className="flex gap-2 pt-2">
                            <button
                                type="button"
                                onClick={onCancel}
                                className="flex-1 px-4 py-2 rounded-lg text-sm font-medium
                                           text-foreground/50 hover:bg-foreground/5 transition-colors"
                            >
                                Cancel
                            </button>
                            <button
                                type="submit"
                                disabled={saving || !title.trim()}
                                className="flex-1 px-4 py-2 rounded-lg text-sm font-medium
                                           bg-foreground text-paper hover:bg-foreground/90 transition-colors
                                           disabled:opacity-40 disabled:cursor-not-allowed"
                            >
                                {saving ? 'Saving...' : isEditing ? 'Save Stop' : 'Add Stop'}
                            </button>
                        </div>
                    </form>
                </div>
            </div>

            {showArchivePicker && (
                <ArchivePhotoPicker
                    onSelect={handleArchiveSelect}
                    onClose={() => setShowArchivePicker(false)}
                    excludeIds={photos.filter(p => p.photoId).map(p => p.photoId!)}
                />
            )}
        </>
    );
}
