'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import { Bot, ChevronDown, ImagePlus, Search, Sparkles, X } from 'lucide-react';
import { useCallback, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select } from '@/components/ui/select';
import { useProjectSearch } from '@/lib/hooks/use-valuation';
import {
  valuationFormSchema,
  type ValuationFormData,
  VALUATION_PROPERTY_TYPES,
  CITIES,
  FLOOD_RISK_OPTIONS,
} from '@/lib/validations/valuation';
import type { ValuationRequest } from '@/lib/valuation-api';

interface ValuationFormProps {
  onSubmit: (data: ValuationRequest) => void;
  isLoading?: boolean;
}

function toNum(val: string | undefined): number | undefined {
  if (!val || val === '') return undefined;
  const n = Number(val);
  return isNaN(n) ? undefined : n;
}

export function ValuationForm({ onSubmit, isLoading }: ValuationFormProps) {
  const {
    register,
    handleSubmit,
    setValue,
    formState: { errors },
  } = useForm<ValuationFormData>({
    resolver: zodResolver(valuationFormSchema),
    defaultValues: {
      city: 'Ho Chi Minh',
      hasLegalPaper: true,
      deepAnalysis: false,
    },
  });

  // Project autocomplete state
  const [projectQuery, setProjectQuery] = useState('');
  const [projectName, setProjectName] = useState('');
  const [showProjectDropdown, setShowProjectDropdown] = useState(false);
  const { data: projectResults } = useProjectSearch(projectQuery);
  const projectInputRef = useRef<HTMLInputElement>(null);

  // Image upload state
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [imageUrl, setImageUrl] = useState<string | null>(null);
  const [uploadProgress, setUploadProgress] = useState<number | null>(null);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // v2 section collapsible state
  const [showV2Section, setShowV2Section] = useState(false);

  const handleProjectSearch = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setProjectQuery(value);
    setProjectName(value);
    setShowProjectDropdown(value.length >= 2);
    if (!value) {
      setValue('projectId', '');
    }
  }, [setValue]);

  const handleSelectProject = useCallback(
    (id: string, name: string) => {
      setValue('projectId', id);
      setProjectName(name);
      setProjectQuery('');
      setShowProjectDropdown(false);
    },
    [setValue],
  );

  const handleImageChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      setUploadError(null);
      if (!file) return;

      // Validate MIME type and size before anything else
      const ALLOWED = ['image/jpeg', 'image/png'];
      if (!ALLOWED.includes(file.type)) {
        setUploadError('Chỉ chấp nhận ảnh JPG hoặc PNG.');
        if (fileInputRef.current) fileInputRef.current.value = '';
        return;
      }
      const MAX_BYTES = 5 * 1024 * 1024;
      if (file.size > MAX_BYTES) {
        setUploadError('Ảnh vượt quá 5MB. Vui lòng chọn ảnh nhỏ hơn.');
        if (fileInputRef.current) fileInputRef.current.value = '';
        return;
      }

      // Simulate progress during local processing (FileReader is synchronous
      // for small files; real uploads to MinIO would track XHR progress).
      setUploadProgress(0);
      const reader = new FileReader();
      reader.onprogress = (ev) => {
        if (ev.lengthComputable) {
          setUploadProgress(Math.round((ev.loaded / ev.total) * 100));
        }
      };
      reader.onload = (ev) => {
        setImagePreview(ev.target?.result as string);
        setUploadProgress(100);
        // Hide the bar after a tick so users see "100%" briefly
        setTimeout(() => setUploadProgress(null), 400);
      };
      reader.onerror = () => {
        setUploadError('Không thể đọc ảnh. Vui lòng thử lại.');
        setUploadProgress(null);
      };
      reader.readAsDataURL(file);

      // For now, use an object URL locally; presigned upload is a separate flow.
      setImageUrl(URL.createObjectURL(file));
    },
    [],
  );

  const handleClearImage = useCallback(() => {
    setImagePreview(null);
    setImageUrl(null);
    setUploadError(null);
    setUploadProgress(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  }, []);

  const handleFormSubmit = (data: ValuationFormData) => {
    onSubmit({
      propertyType: data.propertyType,
      area: Number(data.area),
      district: data.district,
      city: data.city,
      bedrooms: toNum(data.bedrooms),
      bathrooms: toNum(data.bathrooms),
      floors: toNum(data.floors),
      frontage: toNum(data.frontage),
      roadWidth: toNum(data.roadWidth),
      yearBuilt: toNum(data.yearBuilt),
      hasLegalPaper: data.hasLegalPaper,
      projectId: data.projectId || undefined,
      description: data.description || undefined,
      deepAnalysis: data.deepAnalysis,
      imageUrl: imageUrl || undefined,
      // AVM v2
      useV2: data.useV2,
      distanceToHospitalKm: toNum(data.distanceToHospitalKm),
      distanceToParkKm: toNum(data.distanceToParkKm),
      distanceToMallKm: toNum(data.distanceToMallKm),
      floodZoneRisk: data.floodZoneRisk,
      hasElevator: data.hasElevator,
      hasParking: data.hasParking,
      hasPool: data.hasPool,
    });
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle>Định giá bất động sản</CardTitle>
        <CardDescription>
          Nhập thông tin bất động sản để nhận ước tính giá từ AI
        </CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit(handleFormSubmit)} className="space-y-6">
          {/* Project selector (autocomplete) */}
          <div className="space-y-2">
            <Label htmlFor="projectSearch">Dự án (tùy chọn)</Label>
            <div className="relative">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                id="projectSearch"
                ref={projectInputRef}
                value={projectName}
                onChange={handleProjectSearch}
                onFocus={() => projectQuery.length >= 2 && setShowProjectDropdown(true)}
                onBlur={() => setTimeout(() => setShowProjectDropdown(false), 200)}
                placeholder="Tìm kiếm dự án..."
                className="pl-9"
              />
              {projectName && (
                <button
                  type="button"
                  className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                  onClick={() => {
                    setProjectName('');
                    setProjectQuery('');
                    setValue('projectId', '');
                  }}
                >
                  <X className="h-4 w-4" />
                </button>
              )}
              {showProjectDropdown && projectResults?.data && projectResults.data.length > 0 && (
                <div className="absolute left-0 right-0 top-full z-50 mt-1 max-h-48 overflow-auto rounded-md border bg-popover p-1 shadow-md">
                  {projectResults.data.map((project) => (
                    <button
                      key={project.id}
                      type="button"
                      className="flex w-full items-start gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent"
                      onClick={() => handleSelectProject(project.id, project.name)}
                    >
                      <div>
                        <p className="font-medium">{project.name}</p>
                        <p className="text-xs text-muted-foreground">
                          {project.district}, {project.city}
                        </p>
                      </div>
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* Row 1: Property type + City */}
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="propertyType">Loại bất động sản *</Label>
              <Select id="propertyType" {...register('propertyType')}>
                <option value="">-- Chọn loại --</option>
                {VALUATION_PROPERTY_TYPES.map((t) => (
                  <option key={t.value} value={t.value}>
                    {t.label}
                  </option>
                ))}
              </Select>
              {errors.propertyType && (
                <p className="text-sm text-destructive">{errors.propertyType.message}</p>
              )}
            </div>

            <div className="space-y-2">
              <Label htmlFor="city">Tỉnh/Thành phố *</Label>
              <Select id="city" {...register('city')}>
                {CITIES.map((c) => (
                  <option key={c.value} value={c.value}>
                    {c.label}
                  </option>
                ))}
              </Select>
              {errors.city && (
                <p className="text-sm text-destructive">{errors.city.message}</p>
              )}
            </div>
          </div>

          {/* Row 2: District + Area */}
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="district">Quận/Huyện *</Label>
              <Input
                id="district"
                placeholder="VD: Quận 1, Bình Thạnh..."
                {...register('district')}
              />
              {errors.district && (
                <p className="text-sm text-destructive">{errors.district.message}</p>
              )}
            </div>

            <div className="space-y-2">
              <Label htmlFor="area">Diện tích (m²) *</Label>
              <Input
                id="area"
                type="number"
                step="0.1"
                placeholder="VD: 80"
                {...register('area')}
              />
              {errors.area && (
                <p className="text-sm text-destructive">{errors.area.message}</p>
              )}
            </div>
          </div>

          {/* Row 3: Bedrooms + Bathrooms + Floors */}
          <div className="grid gap-4 sm:grid-cols-3">
            <div className="space-y-2">
              <Label htmlFor="bedrooms">Phòng ngủ</Label>
              <Input
                id="bedrooms"
                type="number"
                placeholder="VD: 3"
                {...register('bedrooms')}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="bathrooms">Phòng tắm</Label>
              <Input
                id="bathrooms"
                type="number"
                placeholder="VD: 2"
                {...register('bathrooms')}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="floors">Số tầng</Label>
              <Input
                id="floors"
                type="number"
                placeholder="VD: 4"
                {...register('floors')}
              />
            </div>
          </div>

          {/* Row 4: Frontage + Road Width + Year Built */}
          <div className="grid gap-4 sm:grid-cols-3">
            <div className="space-y-2">
              <Label htmlFor="frontage">Mặt tiền (m)</Label>
              <Input
                id="frontage"
                type="number"
                step="0.1"
                placeholder="VD: 5"
                {...register('frontage')}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="roadWidth">Độ rộng đường (m)</Label>
              <Input
                id="roadWidth"
                type="number"
                step="0.1"
                placeholder="VD: 8"
                {...register('roadWidth')}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="yearBuilt">Năm xây dựng</Label>
              <Input
                id="yearBuilt"
                type="number"
                placeholder="VD: 2020"
                {...register('yearBuilt')}
              />
            </div>
          </div>

          {/* Image upload */}
          <div className="space-y-2">
            <Label>Hình ảnh (tùy chọn)</Label>
            <div className="flex items-start gap-4">
              {imagePreview ? (
                <div className="relative h-24 w-24 overflow-hidden rounded-lg border">
                  <img
                    src={imagePreview}
                    alt="Ảnh bất động sản"
                    className="h-full w-full object-cover"
                  />
                  <button
                    type="button"
                    onClick={handleClearImage}
                    className="absolute right-1 top-1 rounded-full bg-background/80 p-0.5 hover:bg-background"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </div>
              ) : (
                <button
                  type="button"
                  onClick={() => fileInputRef.current?.click()}
                  className="flex h-24 w-24 flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed border-muted-foreground/25 text-muted-foreground hover:border-muted-foreground/50 hover:text-foreground"
                >
                  <ImagePlus className="h-6 w-6" />
                  <span className="text-xs">Tải ảnh</span>
                </button>
              )}
              <input
                ref={fileInputRef}
                type="file"
                accept="image/jpeg,image/png"
                className="hidden"
                onChange={handleImageChange}
              />
              <div className="flex-1 space-y-1">
                <p className="text-xs text-muted-foreground">
                  Tải ảnh bất động sản để AI phân tích trực quan (JPG, PNG, tối đa 5MB)
                </p>
                {uploadProgress != null && (
                  <div
                    role="progressbar"
                    aria-label="Tiến độ tải ảnh"
                    aria-valuenow={uploadProgress}
                    aria-valuemin={0}
                    aria-valuemax={100}
                    className="h-1.5 w-full overflow-hidden rounded-full bg-muted"
                  >
                    <div
                      className="h-full bg-primary transition-all"
                      style={{ width: `${uploadProgress}%` }}
                    />
                  </div>
                )}
                {uploadError && (
                  <p
                    role="alert"
                    data-testid="image-upload-error"
                    className="text-xs text-destructive"
                  >
                    {uploadError}
                  </p>
                )}
              </div>
            </div>
          </div>

          {/* Description textarea */}
          <div className="space-y-2">
            <Label htmlFor="description">Mô tả thêm (tùy chọn)</Label>
            <textarea
              id="description"
              {...register('description')}
              rows={3}
              className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
              placeholder="Mô tả chi tiết về bất động sản: vị trí, hướng, tình trạng, tiện ích lân cận..."
            />
          </div>

          {/* Toggles row */}
          <div className="flex flex-wrap items-center gap-6">
            <div className="flex items-center gap-2">
              <input
                id="hasLegalPaper"
                type="checkbox"
                className="h-4 w-4 rounded border-input"
                {...register('hasLegalPaper')}
              />
              <Label htmlFor="hasLegalPaper">Có sổ đỏ/giấy tờ hợp pháp</Label>
            </div>

            <div className="flex items-center gap-2">
              <input
                id="deepAnalysis"
                type="checkbox"
                className="h-4 w-4 rounded border-input accent-primary"
                {...register('deepAnalysis')}
              />
              <Label htmlFor="deepAnalysis" className="flex items-center gap-1.5">
                <Bot className="h-4 w-4 text-primary" />
                Phân tích chuyên sâu
              </Label>
            </div>

            <div className="flex items-center gap-2">
              <input
                id="useV2"
                type="checkbox"
                className="h-4 w-4 rounded border-input accent-primary"
                {...register('useV2')}
              />
              <Label htmlFor="useV2" className="flex items-center gap-1.5">
                <Sparkles className="h-4 w-4 text-primary" />
                Mô hình v2 (Ensemble)
              </Label>
            </div>
          </div>

          {/* AVM v2 — Extended features (collapsible) */}
          <div className="rounded-lg border bg-muted/30">
            <button
              type="button"
              onClick={() => setShowV2Section(!showV2Section)}
              className="flex w-full items-center justify-between px-4 py-3 text-left text-sm font-medium"
              aria-expanded={showV2Section}
            >
              <span>Đặc trưng mở rộng (AVM v2)</span>
              <ChevronDown
                className={`h-4 w-4 transition-transform ${showV2Section ? 'rotate-180' : ''}`}
                aria-hidden="true"
              />
            </button>
            {showV2Section && (
              <div className="space-y-4 border-t p-4">
                <p className="text-xs text-muted-foreground">
                  Các trường tùy chọn, chỉ sử dụng khi bật &ldquo;Mô hình v2&rdquo;. Bỏ trống sẽ dùng giá trị mặc định.
                </p>

                {/* Distances */}
                <div className="grid gap-4 sm:grid-cols-3">
                  <div className="space-y-2">
                    <Label htmlFor="distanceToHospitalKm">Đến bệnh viện (km)</Label>
                    <Input
                      id="distanceToHospitalKm"
                      type="number"
                      step="0.1"
                      min="0"
                      {...register('distanceToHospitalKm')}
                      placeholder="1.5"
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="distanceToParkKm">Đến công viên (km)</Label>
                    <Input
                      id="distanceToParkKm"
                      type="number"
                      step="0.1"
                      min="0"
                      {...register('distanceToParkKm')}
                      placeholder="0.8"
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="distanceToMallKm">Đến TTTM (km)</Label>
                    <Input
                      id="distanceToMallKm"
                      type="number"
                      step="0.1"
                      min="0"
                      {...register('distanceToMallKm')}
                      placeholder="2.0"
                    />
                  </div>
                </div>

                {/* Flood zone + amenity checkboxes */}
                <div className="grid gap-4 sm:grid-cols-2">
                  <div className="space-y-2">
                    <Label htmlFor="floodZoneRisk">Nguy cơ ngập</Label>
                    <Select id="floodZoneRisk" {...register('floodZoneRisk')}>
                      <option value="">-- Không xác định --</option>
                      {FLOOD_RISK_OPTIONS.map((opt) => (
                        <option key={opt.value} value={opt.value}>
                          {opt.label}
                        </option>
                      ))}
                    </Select>
                  </div>
                  <div className="flex flex-col justify-center gap-2">
                    <div className="flex items-center gap-2">
                      <input
                        id="hasElevator"
                        type="checkbox"
                        className="h-4 w-4 rounded border-input"
                        {...register('hasElevator')}
                      />
                      <Label htmlFor="hasElevator">Có thang máy</Label>
                    </div>
                    <div className="flex items-center gap-2">
                      <input
                        id="hasParking"
                        type="checkbox"
                        className="h-4 w-4 rounded border-input"
                        {...register('hasParking')}
                      />
                      <Label htmlFor="hasParking">Có bãi đậu xe</Label>
                    </div>
                    <div className="flex items-center gap-2">
                      <input
                        id="hasPool"
                        type="checkbox"
                        className="h-4 w-4 rounded border-input"
                        {...register('hasPool')}
                      />
                      <Label htmlFor="hasPool">Có hồ bơi</Label>
                    </div>
                  </div>
                </div>
              </div>
            )}
          </div>

          <Button type="submit" disabled={isLoading} className="w-full sm:w-auto">
            {isLoading ? 'Đang định giá...' : 'Định giá ngay'}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}
