'use client';

import React from 'react';
import { Formik, Form, useField } from 'formik';
import {
  FileText,
  User,
  CheckCircle2,
  Satellite,
  Power,
  Calendar,
  MapPin,
  Car,
  Clock,
  Fuel,
  RotateCw,
  AlertTriangle,
} from 'lucide-react';
import { useTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
import { useSelector } from 'react-redux';
import { RootState } from '@/store';
import { FormTextField, SectionCard, FieldGroup, FormikErrorToast } from '@/components/teltoinstall/_index';
import { useValidationStep, useGpsTest, useAuth, useProvisioningStatus } from '@/hooks/teltoinstall/_index';
import { WIZARD_FORM_ID } from '../constants';

interface Props {
  onNext: () => void;
}

function RecapRow({ label, value }: { label: string; value?: string | null }) {
  return (
    <div className="flex justify-between items-center px-4 py-3">
      <span className="text-sm text-muted-foreground">{label}</span>
      <span className="text-sm font-mono font-medium text-foreground">{value || '—'}</span>
    </div>
  );
}

function GpsRow({
  icon,
  label,
  value,
  hasData,
  stale,
}: {
  icon: React.ReactNode;
  label: string;
  value?: string | number | null;
  hasData?: boolean;
  /** Donnée présente mais trop ancienne : affichée en rouge. */
  stale?: boolean;
}) {
  const tone = !hasData ? 'text-muted-foreground' : stale ? 'text-red-600' : 'text-emerald-600';
  return (
    <div className="validation-row">
      <div className="flex items-center gap-2">
        <span className="text-muted-foreground">{icon}</span>
        <span className="text-sm text-foreground">{label}</span>
      </div>
      <div className="flex items-center gap-2">
        {hasData && <div className={`status-dot ${stale ? 'error' : 'ok'}`} />}
        <span className={`text-sm font-medium ${tone}`}>{value != null ? String(value) : '—'}</span>
      </div>
    </div>
  );
}

/** « il y a 5 min » / « il y a 3 h » / « il y a 2 j » : âge de la position au moment du test. */
function ageLabel(minutes: number, t: TFunction): string {
  if (minutes < 60) return t('validation.ageMinutes', { count: minutes });
  if (minutes < 24 * 60) return t('validation.ageHours', { count: Math.floor(minutes / 60) });
  return t('validation.ageDays', { count: Math.floor(minutes / (24 * 60)) });
}

/** Date de la position, lisible, suivie de son âge au moment du test quand il est connu. */
function positionLabel(iso: string | undefined, ageMinutes: number | null | undefined, t: TFunction): string | null {
  if (!iso) return null;
  const date = new Date(iso);
  const readable = Number.isNaN(date.getTime())
    ? iso
    : date.toLocaleString('fr-FR', { dateStyle: 'short', timeStyle: 'short' });
  return ageMinutes != null ? `${readable} · ${ageLabel(ageMinutes, t)}` : readable;
}

function ReadingRow({
  icon,
  label,
  manualValue,
  gpsValue,
}: {
  icon: React.ReactNode;
  label: string;
  manualValue?: string | number | null;
  gpsValue?: string | number | null;
}) {
  return (
    <div className="grid grid-cols-3 items-center px-4 py-3 gap-2">
      <div className="flex items-center gap-2">
        <span className="text-muted-foreground">{icon}</span>
        <span className="text-sm text-foreground">{label}</span>
      </div>
      <span className="text-sm font-mono font-medium text-foreground text-right">
        {manualValue != null && manualValue !== '' ? String(manualValue) : '—'}
      </span>
      <span
        className={`text-sm font-mono font-medium text-right ${
          gpsValue != null && gpsValue !== '' ? 'text-emerald-600' : 'text-muted-foreground'
        }`}
      >
        {gpsValue != null && gpsValue !== '' ? String(gpsValue) : '—'}
      </span>
    </div>
  );
}

function DateField() {
  const { t } = useTranslation();
  const [field, meta, helpers] = useField('intervention_date');
  const showError = meta.touched && Boolean(meta.error);
  return (
    <FieldGroup label={t('validation.interventionDate')} required error={showError ? meta.error : undefined}>
      <input
        id="intervention_date"
        type="date"
        name="intervention_date"
        onBlur={field.onBlur}
        value={(field.value as string) ?? ''}
        onChange={(e) => helpers.setValue(e.target.value)}
        className={`field-input ${showError ? 'border-red-400 focus:ring-red-200 focus:border-red-400' : ''}`}
      />
    </FieldGroup>
  );
}

export default function ValidationStep({ onNext }: Props) {
  const { t } = useTranslation();
  const { installer_name, intervention_date, validationSchema, vehicle, device, saveInstallerInfo } =
    useValidationStep();
  const { runTest, loading: gpsLoading, error: gpsError, result: gpsResult } = useGpsTest();
  const { user } = useAuth();
  // Provisionnement (task Teltonika + device Flespi) encore en cours : on bloque
  // le test de connexion tant que la configuration du boîtier n'est pas terminée.
  const installationId = useSelector((s: RootState) => s.installation.installationId);
  const {
    configuring,
    failed: provisioningFailed,
    error: provisioningError,
    retry: retryProvisioning,
    retrying,
  } = useProvisioningStatus(installationId);
  const positionStale = gpsResult?.gps_fresh === false;

  const today = new Date().toLocaleDateString('en-CA');

  return (
    <Formik
      initialValues={{
        installer_name: installer_name || user?.name || '',
        intervention_date: intervention_date || today,
      }}
      validationSchema={validationSchema}
      enableReinitialize
      onSubmit={async (values) => {
        const ok = await saveInstallerInfo(values);
        if (ok) onNext();
      }}
    >
      <Form id={WIZARD_FORM_ID}>
        <FormikErrorToast />
        <SectionCard icon={<FileText className="w-4 h-4" />} title={t('validation.recapTitle')} noPadding>
          <div className="divide-y divide-border">
            <RecapRow label={t('validation.licensePlate')} value={vehicle.license_plate} />
            <RecapRow label={t('validation.vin')} value={vehicle.vin} />
            <RecapRow label={t('validation.deviceType')} value={device.product_line} />
            <RecapRow label={t('validation.imei')} value={device.imei} />
            <RecapRow label={t('validation.iccid')} value={device.sim_card?.iccid} />
          </div>
        </SectionCard>

        <SectionCard icon={<User className="w-4 h-4" />} title={t('validation.sectionInstaller')}>
          <FormTextField name="installer_name" label={t('validation.installer')} required />
          <DateField />
        </SectionCard>

        <SectionCard icon={<CheckCircle2 className="w-4 h-4" />} title={t('validation.sectionValidation')}>
          <button
            type="button"
            onClick={runTest}
            disabled={gpsLoading || configuring}
            className={`btn-primary flex items-center justify-center gap-2 ${gpsLoading || configuring ? 'opacity-70' : ''}`}
          >
            {configuring ? (
              <>
                <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                {t('validation.configuring')}
              </>
            ) : gpsLoading ? (
              <>
                <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                {t('validation.testRunning')}
              </>
            ) : (
              <>
                <Satellite className="w-4 h-4" />
                {t('validation.runGpsTest')}
              </>
            )}
          </button>

          {provisioningFailed && (
            <div className="flex flex-col gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
              <div className="flex items-center gap-2">
                <AlertTriangle className="w-4 h-4 text-red-600 shrink-0" />
                <p className="text-sm font-medium text-red-700">{t('validation.provisioningFailed')}</p>
              </div>
              {provisioningError && <p className="text-sm text-red-600">{provisioningError}</p>}
              <button
                type="button"
                onClick={retryProvisioning}
                disabled={retrying}
                className={`btn-secondary flex items-center justify-center gap-2 ${retrying ? 'opacity-70' : ''}`}
              >
                <RotateCw className={`w-4 h-4 ${retrying ? 'animate-spin' : ''}`} />
                {retrying ? t('validation.provisioningRetrying') : t('validation.provisioningRetry')}
              </button>
            </div>
          )}

          {gpsError && (
            <div className="flex items-center gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
              <p className="text-sm text-red-600">{gpsError}</p>
            </div>
          )}

          {positionStale && (
            <div className="flex items-start gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
              <AlertTriangle className="w-4 h-4 text-red-600 shrink-0 mt-0.5" />
              <p className="text-sm text-red-600">
                {t('validation.gpsStale', { max: gpsResult?.gps_max_age_minutes ?? 60 })}
              </p>
            </div>
          )}

          <div className="divide-y divide-border border border-border rounded-xl overflow-hidden">
            <GpsRow
              icon={<Power className="w-4 h-4" />}
              label={t('validation.contactDetected')}
              value={
                gpsResult?.contact_detected != null
                  ? gpsResult.contact_detected
                    ? '✓ Détecté'
                    : '✗ Non détecté'
                  : null
              }
              hasData={gpsResult?.contact_detected != null}
            />
            <GpsRow
              icon={<Calendar className="w-4 h-4" />}
              label={t('validation.gpsPositionDate')}
              value={positionLabel(gpsResult?.gps_position_date, gpsResult?.gps_age_minutes, t)}
              hasData={!!gpsResult?.gps_position_date}
              stale={positionStale}
            />
            <GpsRow
              icon={<MapPin className="w-4 h-4" />}
              label={t('validation.gpsAddress')}
              value={gpsResult?.gps_address}
              hasData={!!gpsResult?.gps_address}
            />
            <GpsRow
              icon={<Satellite className="w-4 h-4" />}
              label={t('validation.satelliteCount')}
              value={gpsResult?.satellite_count != null ? `${gpsResult.satellite_count} satellites` : null}
              hasData={gpsResult?.satellite_count != null}
            />
          </div>

          <div className="border border-border rounded-xl overflow-hidden">
            <div className="grid grid-cols-3 items-center px-4 py-2.5 bg-muted/40 gap-2">
              <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">
                {t('validation.reading')}
              </span>
              <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wide text-right">
                {t('validation.sourceManual')}
              </span>
              <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wide text-right">
                {t('validation.sourceGps')}
              </span>
            </div>
            <div className="divide-y divide-border">
              <ReadingRow
                icon={<Car className="w-4 h-4" />}
                label={t('validation.odometerKm')}
                manualValue={vehicle.odometer_km != null ? `${vehicle.odometer_km} km` : null}
                gpsValue={gpsResult?.odometer_km != null ? `${gpsResult.odometer_km} km` : null}
              />
              <ReadingRow
                icon={<Clock className="w-4 h-4" />}
                label={t('validation.hourMeter')}
                manualValue={vehicle.hour_meter != null ? `${vehicle.hour_meter} min` : null}
                gpsValue={gpsResult?.hour_meter != null ? `${gpsResult.hour_meter} min` : null}
              />
              <ReadingRow
                icon={<Fuel className="w-4 h-4" />}
                label={t('validation.fuelLevel')}
                manualValue={vehicle.fuel_level ? t(`validation.fuelLevels.${vehicle.fuel_level}`) : null}
                gpsValue={gpsResult?.fuel_level ? t(`validation.fuelLevels.${gpsResult.fuel_level}`) : null}
              />
            </div>
          </div>
        </SectionCard>
      </Form>
    </Formik>
  );
}
