import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import { MultiSelect } from '@/components/ui/multi-selector';
import { Slider } from '@/components/ui/slider';
import { useTranslation } from '@/hooks/use-translation';
import { cn } from '@/lib/utils';
import { MapPin, RefreshCcw, SearchIcon, User } from 'lucide-react';
import { useMemo, useState } from 'react';

const FALLBACK_IMAGE = 'https://placeholder.pics/svg/330x210/DEDEDE/555555/not%20found';
const PRICE_MIN = 0;
const PRICE_MAX = 4000;

type PickerProperty = {
    uid: string;
    name: string | null;
    internal_name: string | null;
    image: string | null;
    location: string | null;
    type: string | null;
    owner: string | null;
    current_price: number | null;
    street: string | null;
};

type PropertyPickerProps = {
    properties: PickerProperty[];
    selectedUids: string[];
    onChange: (uids: string[]) => void;
    disabled?: boolean;
};

type PriceRange = { from: number; to: number };

/** Distinct, non-empty values sorted alphabetically — used to build filter options. */
const distinctValues = (values: (string | null)[]): string[] =>
    Array.from(new Set(values.filter((value): value is string => value !== null && value !== ''))).sort((a, b) => a.localeCompare(b));

/**
 * Filterable card grid of the account's properties, mirroring the visual
 * language of the /logements list (search bar, multi-select filters, price
 * slider, mini logement cards). All filters combine with AND logic.
 * "Select all" only targets the currently filtered results: toggling it
 * adds/removes those cards without touching properties selected under
 * another filter combination.
 */
export default function PropertyPicker({ properties, selectedUids, onChange, disabled }: PropertyPickerProps) {
    const { t } = useTranslation();
    const [search, setSearch] = useState('');
    const [locations, setLocations] = useState<string[]>([]);
    const [types, setTypes] = useState<string[]>([]);
    const [owners, setOwners] = useState<string[]>([]);
    const [priceRange, setPriceRange] = useState<PriceRange>({ from: PRICE_MIN, to: PRICE_MAX });

    const locationOptions = useMemo(() => distinctValues(properties.map((property) => property.location)), [properties]);
    const typeOptions = useMemo(() => distinctValues(properties.map((property) => property.type)), [properties]);
    const ownerOptions = useMemo(() => distinctValues(properties.map((property) => property.owner)), [properties]);

    const fullPriceRange = priceRange.from === PRICE_MIN && priceRange.to === PRICE_MAX;

    const filtered = useMemo(() => {
        const term = search.trim().toLowerCase();

        return properties.filter((property) => {
            if (term !== '' && !(property.name ?? '').toLowerCase().includes(term) && !(property.internal_name ?? '').toLowerCase().includes(term)) {
                return false;
            }
            if (locations.length > 0 && (property.location === null || !locations.includes(property.location))) {
                return false;
            }
            if (types.length > 0 && (property.type === null || !types.includes(property.type))) {
                return false;
            }
            if (owners.length > 0 && (property.owner === null || !owners.includes(property.owner))) {
                return false;
            }
            // Full range = no price filtering (properties without a price pass through).
            if (!fullPriceRange && (property.current_price === null || property.current_price < priceRange.from || property.current_price > priceRange.to)) {
                return false;
            }
            return true;
        });
    }, [properties, search, locations, types, owners, fullPriceRange, priceRange]);

    const allFilteredSelected = filtered.length > 0 && filtered.every((property) => selectedUids.includes(property.uid));

    const toggleUid = (uid: string) => {
        onChange(selectedUids.includes(uid) ? selectedUids.filter((u) => u !== uid) : [...selectedUids, uid]);
    };

    const toggleAllFiltered = () => {
        const filteredUids = filtered.map((property) => property.uid);
        if (allFilteredSelected) {
            onChange(selectedUids.filter((uid) => !filteredUids.includes(uid)));
        } else {
            onChange(Array.from(new Set([...selectedUids, ...filteredUids])));
        }
    };

    const resetFilters = () => {
        setSearch('');
        setLocations([]);
        setTypes([]);
        setOwners([]);
        setPriceRange({ from: PRICE_MIN, to: PRICE_MAX });
    };

    return (
        <div className="flex flex-col gap-3 rounded-lg border p-4">
            <div className="flex flex-wrap items-center gap-2">
                <div
                    className={cn(
                        'border-input ring-offset-background focus-within:ring-ring flex h-10 w-full max-w-sm items-center rounded-full border bg-white pl-3 text-sm focus-within:ring-1 focus-within:ring-offset-2',
                    )}
                >
                    <SearchIcon className="text-muted-foreground h-[16px] w-[16px]" />
                    <input
                        type="text"
                        placeholder={t('properties.bulk-edit', 'search_properties')}
                        className="placeholder:text-muted-foreground w-full p-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
                        value={search}
                        onChange={(e) => setSearch(e.target.value)}
                        disabled={disabled}
                    />
                </div>
                <Button
                    variant="ghost"
                    className="cursor-pointer"
                    onClick={resetFilters}
                    disabled={disabled}
                    title={t('properties.bulk-edit', 'reset_filters')}
                    aria-label={t('properties.bulk-edit', 'reset_filters')}
                >
                    <RefreshCcw className="h-4 w-4" />
                </Button>
            </div>

            <div
                className={cn('grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4', disabled && 'pointer-events-none opacity-50 select-none')}
                aria-disabled={disabled}
            >
                <div>
                    <Label className="mb-2 block">{t('properties.index', 'location')}</Label>
                    <MultiSelect options={locationOptions} selected={locations} onChange={setLocations} />
                </div>
                <div>
                    <Label className="mb-2 block">Type</Label>
                    <MultiSelect options={typeOptions} selected={types} onChange={setTypes} />
                </div>
                <div>
                    <Label className="mb-2 block">{t('properties.bulk-edit', 'owner')}</Label>
                    <MultiSelect options={ownerOptions} selected={owners} onChange={setOwners} />
                </div>
                <div>
                    <Label className="mb-2 block">{t('properties.index', 'price_range')}</Label>
                    <div className="flex w-full items-center justify-between gap-2">
                        <span className="text-muted-foreground text-sm">{PRICE_MIN}</span>
                        <Slider
                            value={[priceRange.from, priceRange.to]}
                            onValueChange={(value) => setPriceRange({ from: value[0] ?? PRICE_MIN, to: value[1] ?? PRICE_MAX })}
                            max={PRICE_MAX}
                            min={PRICE_MIN}
                            step={100}
                            disabled={disabled}
                        />
                        <span className="text-muted-foreground text-sm">{PRICE_MAX}</span>
                    </div>
                    <p className="text-muted-foreground mt-2 text-center text-sm">
                        {priceRange.from} - {priceRange.to}
                    </p>
                </div>
            </div>

            <div className="flex flex-wrap items-center justify-between gap-2">
                <label className="flex w-fit cursor-pointer items-center gap-2 text-sm font-medium">
                    <Checkbox checked={allFilteredSelected} onCheckedChange={toggleAllFiltered} disabled={disabled || filtered.length === 0} />
                    {t('properties.bulk-edit', 'select_all_results')}
                </label>
                <span className="text-muted-foreground text-sm">
                    {selectedUids.length} {t('properties.bulk-edit', 'editing_count')}
                </span>
            </div>

            {filtered.length === 0 ? (
                <p className="text-muted-foreground p-4 text-sm">{t('properties.bulk-edit', 'no_properties_found')}</p>
            ) : (
                <div className="max-h-[36rem] overflow-y-auto p-1">
                    <div className="grid grid-cols-[repeat(auto-fill,minmax(13rem,1fr))] gap-3">
                        {filtered.map((property) => {
                            const selected = selectedUids.includes(property.uid);

                            return (
                                <Card
                                    key={property.uid}
                                    role="button"
                                    aria-pressed={selected}
                                    tabIndex={disabled ? -1 : 0}
                                    onClick={() => {
                                        if (!disabled) {
                                            toggleUid(property.uid);
                                        }
                                    }}
                                    onKeyDown={(e) => {
                                        if (!disabled && (e.key === 'Enter' || e.key === ' ')) {
                                            e.preventDefault();
                                            toggleUid(property.uid);
                                        }
                                    }}
                                    className={cn(
                                        'gap-0 overflow-hidden py-0 pt-0 transition-shadow',
                                        disabled ? 'cursor-default' : 'cursor-pointer hover:shadow-md',
                                        selected && 'ring-secondary ring-2',
                                    )}
                                >
                                    <div className="relative">
                                        <img
                                            src={property.image ?? FALLBACK_IMAGE}
                                            alt={property.name ?? property.uid}
                                            className="h-28 w-full rounded-t-lg object-cover"
                                            onError={(e) => {
                                                e.currentTarget.onerror = null; // Prevent infinite loop
                                                e.currentTarget.src = FALLBACK_IMAGE;
                                            }}
                                        />
                                        <Checkbox
                                            checked={selected}
                                            tabIndex={-1}
                                            aria-hidden
                                            className="pointer-events-none absolute top-2 left-2 size-5 border-2 bg-white shadow-md"
                                        />
                                    </div>
                                    <div className="flex flex-1 flex-col gap-1 p-3">
                                        <p className="truncate text-sm font-semibold">{property.name ?? property.uid}</p>
                                        {property.internal_name && <p className="truncate text-xs text-gray-400">({property.internal_name})</p>}
                                        {property.location && (
                                            <div className="text-muted-foreground flex items-center gap-1 text-xs">
                                                <MapPin className="h-3.5 w-3.5 shrink-0 text-gray-500" />
                                                <span className="truncate">{property.location}</span>
                                            </div>
                                        )}
                                        {property.owner && (
                                            <div className="text-muted-foreground flex items-center gap-1 text-xs">
                                                <User className="h-3.5 w-3.5 shrink-0 text-gray-500" />
                                                <span className="truncate">{property.owner}</span>
                                            </div>
                                        )}
                                        {property.current_price !== null && (
                                            <p className="mt-auto pt-1 text-sm font-semibold">
                                                {property.current_price} TND{' '}
                                                <span className="text-xs font-normal">{t('properties.logement-card', 'per_night')}</span>
                                            </p>
                                        )}
                                    </div>
                                </Card>
                            );
                        })}
                    </div>
                </div>
            )}
        </div>
    );
}
