/**
 * @ai-summary Vehicle form component for create/edit with dropdown cascades
 */

import React, { useState, useEffect, useRef } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '../../../shared-minimal/components/Button';
import { CreateVehicleRequest } from '../types/vehicles.types';
import { vehiclesApi } from '../api/vehicles.api';

const vehicleSchema = z
  .object({
    vin: z.string().optional(),
    year: z.number().min(1980).max(new Date().getFullYear() + 1).optional(),
    make: z.string().optional(),
    model: z.string().optional(),
    engine: z.string().optional(),
    transmission: z.string().optional(),
    trimLevel: z.string().optional(),
    driveType: z.string().optional(),
    fuelType: z.string().optional(),
    nickname: z.string().optional(),
    color: z.string().optional(),
    licensePlate: z.string().optional(),
    odometerReading: z.number().min(0).optional(),
  })
  .refine(
    (data) => {
      const vin = (data.vin || '').trim();
      const plate = (data.licensePlate || '').trim();
      // Must have either a valid 17-char VIN or a non-empty license plate
      if (vin.length === 17) return true;
      if (plate.length > 0) return true;
      return false;
    },
    {
      message: 'Either a valid 17-character VIN or a license plate is required',
      path: ['vin'],
    }
  )
  .refine(
    (data) => {
      const vin = (data.vin || '').trim();
      const plate = (data.licensePlate || '').trim();
      // If VIN provided but not 17 and no plate, fail; if plate exists, allow any VIN (or empty)
      if (plate.length > 0) return true;
      return vin.length === 17 || vin.length === 0;
    },
    {
      message: 'VIN must be exactly 17 characters when license plate is not provided',
      path: ['vin'],
    }
  );

interface VehicleFormProps {
  onSubmit: (data: CreateVehicleRequest) => void;
  onCancel: () => void;
  initialData?: Partial<CreateVehicleRequest>;
  loading?: boolean;
}

export const VehicleForm: React.FC<VehicleFormProps> = ({
  onSubmit,
  onCancel,
  initialData,
  loading,
}) => {
  const [years, setYears] = useState<number[]>([]);
  const [makes, setMakes] = useState<string[]>([]);
  const [models, setModels] = useState<string[]>([]);
  const [engines, setEngines] = useState<string[]>([]);
  const [trims, setTrims] = useState<string[]>([]);
  const [transmissions, setTransmissions] = useState<string[]>([]);
  const [selectedYear, setSelectedYear] = useState<number | undefined>();
  const [selectedMake, setSelectedMake] = useState<string>('');
  const [selectedModel, setSelectedModel] = useState<string>('');
  const [selectedTrim, setSelectedTrim] = useState<string>('');
  const [loadingDropdowns, setLoadingDropdowns] = useState(false);
  const [decodingVIN, setDecodingVIN] = useState(false);
  const [decodeSuccess, setDecodeSuccess] = useState(false);
  const hasInitialized = useRef(false);
  const isInitializing = useRef(false);

  const {
    register,
    handleSubmit,
    formState: { errors },
    watch,
    setValue,
    reset,
  } = useForm<CreateVehicleRequest>({
    resolver: zodResolver(vehicleSchema),
    defaultValues: initialData,
  });

  const watchedYear = watch('year');
  const watchedMake = watch('make');
  const watchedModel = watch('model');
  const watchedVIN = watch('vin');

  // VIN decode handler
  const handleDecodeVIN = async () => {
    const vin = watchedVIN;
    if (!vin || vin.length !== 17) {
      return;
    }

    setDecodingVIN(true);
    setDecodeSuccess(false);
    
    try {
      const result = await vehiclesApi.decodeVIN(vin);
      if (result.success) {
        // Auto-populate fields with decoded values
        if (result.year) setValue('year', result.year);
        if (result.make) setValue('make', result.make);
        if (result.model) setValue('model', result.model);
        if (result.transmission) setValue('transmission', result.transmission);
        if (result.engine) setValue('engine', result.engine);
        if (result.trimLevel) setValue('trimLevel', result.trimLevel);
        
        setDecodeSuccess(true);
        setTimeout(() => setDecodeSuccess(false), 3000); // Hide success after 3 seconds
      }
    } catch (error) {
      console.error('VIN decode failed:', error);
    } finally {
      setDecodingVIN(false);
    }
  };

  // Load years on component mount
  useEffect(() => {
    const loadYears = async () => {
      try {
        const yearsData = await vehiclesApi.getYears();
        setYears(yearsData);
      } catch (error) {
        console.error('Failed to load years:', error);
      }
    };

    loadYears();
  }, []);

  // Initialize dropdowns when editing existing vehicle
  useEffect(() => {
    const initializeEditMode = async () => {
      // Only run once and only if we have initialData
      if (hasInitialized.current || !initialData || !initialData.year) return;
      hasInitialized.current = true;
      isInitializing.current = true;

      try {
        setLoadingDropdowns(true);

        // Step 1: Set year and load makes
        setSelectedYear(initialData.year);
        const makesData = await vehiclesApi.getMakes(initialData.year);
        setMakes(makesData);

        if (!initialData.make) {
          isInitializing.current = false;
          return;
        }

        // Step 2: Set make and load models
        setSelectedMake(initialData.make);
        const modelsData = await vehiclesApi.getModels(initialData.year, initialData.make);
        setModels(modelsData);

        if (!initialData.model) {
          isInitializing.current = false;
          return;
        }

        // Step 3: Set model and load trims + transmissions
        setSelectedModel(initialData.model);
        const [trimsData, transmissionsData] = await Promise.all([
          vehiclesApi.getTrims(initialData.year, initialData.make, initialData.model),
          vehiclesApi.getTransmissions(initialData.year, initialData.make, initialData.model)
        ]);
        setTrims(trimsData);
        setTransmissions(transmissionsData);

        if (initialData.trimLevel) {
          // Step 4: Set trim and load engines
          setSelectedTrim(initialData.trimLevel);
          const enginesData = await vehiclesApi.getEngines(
            initialData.year,
            initialData.make,
            initialData.model,
            initialData.trimLevel
          );
          setEngines(enginesData);
        }

        isInitializing.current = false;
      } catch (error) {
        console.error('Failed to initialize edit mode:', error);
        isInitializing.current = false;
      } finally {
        setLoadingDropdowns(false);
      }
    };

    initializeEditMode();
  }, [initialData]); // Run when initialData is available

  // Reset form values after initialization
  useEffect(() => {
    if (!isInitializing.current && initialData) {
      reset(initialData);
    }
  }, [initialData, reset]);

  // Load makes when year changes
  useEffect(() => {
    // Skip during initialization
    if (isInitializing.current) return;

    if (watchedYear && watchedYear !== selectedYear) {
      const loadMakes = async () => {
        setLoadingDropdowns(true);
        try {
          const makesData = await vehiclesApi.getMakes(watchedYear);
          setMakes(makesData);
          setSelectedYear(watchedYear);

          // Clear dependent selections
          setSelectedMake('');
          setSelectedModel('');
          setSelectedTrim('');
          setModels([]);
          setTrims([]);
          setEngines([]);
          setTransmissions([]);
          setValue('make', '');
          setValue('model', '');
          setValue('trimLevel', '');
          setValue('transmission', '');
          setValue('engine', '');
        } catch (error) {
          console.error('Failed to load makes:', error);
          setMakes([]);
        } finally {
          setLoadingDropdowns(false);
        }
      };

      loadMakes();
    }
  }, [watchedYear, selectedYear, setValue]);

  // Load models when make changes
  useEffect(() => {
    // Skip during initialization
    if (isInitializing.current) return;

    if (watchedMake && watchedYear && watchedMake !== selectedMake) {
      const loadModels = async () => {
        setLoadingDropdowns(true);
        try {
          const modelsData = await vehiclesApi.getModels(watchedYear, watchedMake);
          setModels(modelsData);
          setSelectedMake(watchedMake);

          // Clear dependent selections
          setSelectedModel('');
          setSelectedTrim('');
          setTrims([]);
          setEngines([]);
          setTransmissions([]);
          setValue('model', '');
          setValue('trimLevel', '');
          setValue('transmission', '');
          setValue('engine', '');
        } catch (error) {
          console.error('Failed to load models:', error);
          setModels([]);
        } finally {
          setLoadingDropdowns(false);
        }
      };

      loadModels();
    }
  }, [watchedMake, watchedYear, selectedMake, setValue]);

  // Load trims and transmissions when model changes
  useEffect(() => {
    // Skip during initialization
    if (isInitializing.current) return;

    if (watchedModel && watchedYear && selectedMake && watchedModel !== selectedModel) {
      const loadTrimsAndTransmissions = async () => {
        setLoadingDropdowns(true);
        try {
          const [trimsData, transmissionsData] = await Promise.all([
            vehiclesApi.getTrims(watchedYear, selectedMake, watchedModel),
            vehiclesApi.getTransmissions(watchedYear, selectedMake, watchedModel)
          ]);
          setTrims(trimsData);
          setTransmissions(transmissionsData);
          setSelectedModel(watchedModel);

          // Clear deeper selections
          setSelectedTrim('');
          setEngines([]);
          setValue('trimLevel', '');
          setValue('engine', '');
        } catch (error) {
          console.error('Failed to load trims and transmissions:', error);
          setTrims([]);
          setTransmissions([]);
        } finally {
          setLoadingDropdowns(false);
        }
      };

      loadTrimsAndTransmissions();
    }
  }, [watchedModel, watchedYear, selectedMake, selectedModel, setValue]);

  // Load engines when trim changes
  useEffect(() => {
    // Skip during initialization
    if (isInitializing.current) return;

    const trimName = watch('trimLevel');
    if (trimName && watchedYear && selectedMake && selectedModel) {
      const loadEngines = async () => {
        setLoadingDropdowns(true);
        try {
          const enginesData = await vehiclesApi.getEngines(
            watchedYear,
            selectedMake,
            selectedModel,
            trimName
          );
          setEngines(enginesData);
          setSelectedTrim(trimName);
        } catch (error) {
          console.error('Failed to load engines:', error);
          setEngines([]);
        } finally {
          setLoadingDropdowns(false);
        }
      };

      loadEngines();
    }
  }, [watchedYear, selectedMake, selectedModel, watch('trimLevel')]);

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">
          VIN or License Plate <span className="text-red-500">*</span>
        </label>
        <p className="text-xs text-gray-600 mb-2">
          Enter VIN to auto-fill vehicle details OR manually select from dropdowns below
        </p>
        <div className="flex flex-col sm:flex-row gap-2">
          <input
            {...register('vin')}
            className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 text-base"
            placeholder="Enter 17-character VIN (optional if License Plate provided)"
            style={{ fontSize: '16px' }}
          />
          <Button
            type="button"
            onClick={handleDecodeVIN}
            loading={decodingVIN}
            disabled={!watchedVIN || watchedVIN.length !== 17}
            variant="secondary"
            className="w-full sm:w-auto min-h-[44px]"
          >
            Decode VIN
          </Button>
        </div>
        {decodeSuccess && (
          <p className="mt-1 text-sm text-green-600">VIN decoded successfully! Fields populated.</p>
        )}
        {errors.vin && (
          <p className="mt-1 text-sm text-red-600">{errors.vin.message}</p>
        )}
     </div>

      {/* Vehicle Specification Dropdowns */}
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Year
          </label>
          <select
            {...register('year', { valueAsNumber: true })}
            value={selectedYear || ''}
            onChange={(e) => {
              const year = parseInt(e.target.value);
              setValue('year', year);
            }}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            style={{ fontSize: '16px' }}
          >
            <option value="">Select Year</option>
            {years.map((year) => (
              <option key={year} value={year}>
                {year}
              </option>
            ))}
          </select>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Make
          </label>
          <select
            {...register('make')}
            value={selectedMake}
            onChange={(e) => {
              const make = e.target.value;
              setValue('make', make);
            }}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            disabled={loadingDropdowns || !watchedYear || makes.length === 0}
            style={{ fontSize: '16px' }}
          >
            <option value="">
              {loadingDropdowns
                ? 'Loading...'
                : !watchedYear
                ? 'Select year first'
                : makes.length === 0
                ? 'No makes available'
                : 'Select Make'}
            </option>
            {makes.map((make) => (
              <option key={make} value={make}>
                {make}
              </option>
            ))}
          </select>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Model
          </label>
          <select
            {...register('model')}
            value={selectedModel}
            onChange={(e) => {
              const model = e.target.value;
              setValue('model', model);
            }}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            disabled={loadingDropdowns || !watchedMake || models.length === 0}
            style={{ fontSize: '16px' }}
          >
            <option value="">
              {loadingDropdowns
                ? 'Loading...'
                : !watchedMake
                ? 'Select make first'
                : models.length === 0
                ? 'No models available'
                : 'Select Model'}
            </option>
            {models.map((model) => (
              <option key={model} value={model}>
                {model}
              </option>
            ))}
          </select>
        </div>
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
        {/* Trim (left) */}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Trim
          </label>
          <select
            {...register('trimLevel')}
            value={selectedTrim}
            onChange={(e) => {
              const trim = e.target.value;
              setValue('trimLevel', trim);
            }}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            disabled={loadingDropdowns || !watchedModel || trims.length === 0}
            style={{ fontSize: '16px' }}
          >
            <option value="">
              {loadingDropdowns
                ? 'Loading...'
                : !watchedModel
                ? 'Select model first'
                : trims.length === 0
                ? 'No trims available'
                : 'Select Trim'}
            </option>
            {trims.map((trim) => (
              <option key={trim} value={trim}>
                {trim}
              </option>
            ))}
          </select>
        </div>

        {/* Engine (middle) */}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Engine
          </label>
          <select
            {...register('engine')}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            disabled={loadingDropdowns || !selectedTrim || engines.length === 0}
            style={{ fontSize: '16px' }}
          >
            <option value="">
              {loadingDropdowns
                ? 'Loading...'
                : !selectedTrim
                ? 'Select trim first'
                : engines.length === 0
                ? 'N/A (Electric)'
                : 'Select Engine'}
            </option>
            {engines.map((engine) => (
              <option key={engine} value={engine}>
                {engine}
              </option>
            ))}
          </select>
        </div>

        {/* Transmission (right) */}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Transmission
          </label>
          <select
            {...register('transmission')}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            disabled={loadingDropdowns || !watchedModel || transmissions.length === 0}
            style={{ fontSize: '16px' }}
          >
            <option value="">
              {loadingDropdowns
                ? 'Loading...'
                : !watchedModel
                ? 'Select model first'
                : transmissions.length === 0
                ? 'No transmissions available'
                : 'Select Transmission'}
            </option>
            {transmissions.map((transmission) => (
              <option key={transmission} value={transmission}>
                {transmission}
              </option>
            ))}
          </select>
        </div>
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">
          Nickname
        </label>
        <input
          {...register('nickname')}
          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
          placeholder="e.g., Family Car"
          style={{ fontSize: '16px' }}
        />
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Color
          </label>
          <input
            {...register('color')}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            placeholder="e.g., Blue"
            style={{ fontSize: '16px' }}
          />
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            License Plate
          </label>
          <input
            {...register('licensePlate')}
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
            placeholder="e.g., ABC-123 (required if VIN omitted)"
            style={{ fontSize: '16px' }}
          />
          {errors.licensePlate && (
            <p className="mt-1 text-sm text-red-600">{errors.licensePlate.message}</p>
          )}
        </div>
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">
          Current Odometer Reading
        </label>
        <input
          {...register('odometerReading', { valueAsNumber: true })}
          type="number"
          inputMode="numeric"
          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-[44px]"
          placeholder="e.g., 50000"
          style={{ fontSize: '16px' }}
        />
      </div>

      <div className="flex gap-3 justify-end pt-4">
        <Button variant="secondary" onClick={onCancel} type="button">
          Cancel
        </Button>
        <Button type="submit" loading={loading || loadingDropdowns}>
          {initialData ? 'Update Vehicle' : 'Add Vehicle'}
        </Button>
      </div>
    </form>
  );
};
