'use client';

import { useEffect, useState } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select } from '@/components/ui/select';
import { api, ApiError } from '@/lib/api';

interface Trainer {
  id: string;
  firstName: string;
  lastName: string;
}

interface Client {
  id: string;
  firstName: string;
  lastName: string;
  phone: string;
}

interface TimeSlot {
  startTime: string;
  endTime: string;
}

interface CreateVptDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCreated: () => void;
}

export function CreateVptDialog({
  open,
  onOpenChange,
  onCreated,
}: CreateVptDialogProps) {
  const [trainers, setTrainers] = useState<Trainer[]>([]);
  const [clients, setClients] = useState<Client[]>([]);
  const [slots, setSlots] = useState<TimeSlot[]>([]);

  const [trainerId, setTrainerId] = useState('');
  const [clientId, setClientId] = useState('');
  const [date, setDate] = useState('');
  const [time, setTime] = useState('');
  const [duration, setDuration] = useState('60');
  const [clientSearch, setClientSearch] = useState('');

  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [loadingTrainers, setLoadingTrainers] = useState(false);
  const [loadingClients, setLoadingClients] = useState(false);
  const [loadingSlots, setLoadingSlots] = useState(false);

  // Reset form when dialog opens
  useEffect(() => {
    if (open) {
      setTrainerId('');
      setClientId('');
      setDate(toLocalDate(new Date()));
      setTime('');
      setDuration('60');
      setClientSearch('');
      setError(null);
      setSlots([]);
    }
  }, [open]);

  // Load trainers on open
  useEffect(() => {
    if (!open) return;
    setLoadingTrainers(true);
    api
      .get<Trainer[]>('/users/trainers')
      .then(setTrainers)
      .catch(() => setTrainers([]))
      .finally(() => setLoadingTrainers(false));
  }, [open]);

  // Search clients with debounce
  useEffect(() => {
    if (!open || clientSearch.length < 2) {
      setClients([]);
      return;
    }
    const timer = setTimeout(() => {
      setLoadingClients(true);
      api
        .get<{ data: Client[] }>(`/clients?search=${encodeURIComponent(clientSearch)}&limit=20`)
        .then((res) => setClients(res.data))
        .catch(() => setClients([]))
        .finally(() => setLoadingClients(false));
    }, 300);
    return () => clearTimeout(timer);
  }, [open, clientSearch]);

  // Load available slots when trainer + date selected
  useEffect(() => {
    if (!trainerId || !date) {
      setSlots([]);
      return;
    }
    setLoadingSlots(true);
    api
      .get<TimeSlot[]>(`/trainings/slots/${trainerId}/${date}`)
      .then(setSlots)
      .catch(() => setSlots([]))
      .finally(() => setLoadingSlots(false));
  }, [trainerId, date]);

  const handleSubmit = async () => {
    if (!clientId) {
      setError('Выберите клиента');
      return;
    }
    if (!trainerId) {
      setError('Выберите тренера');
      return;
    }
    if (!date || !time) {
      setError('Укажите дату и время');
      return;
    }

    setLoading(true);
    setError(null);

    try {
      const scheduledAt = `${date}T${time}:00.000Z`;
      await api.post('/trainings', {
        clientId,
        trainerId,
        scheduledAt,
        duration: parseInt(duration, 10),
      });
      onOpenChange(false);
      onCreated();
    } catch (err: unknown) {
      setError(
        err instanceof ApiError
          ? err.message
          : 'Не удалось создать запись',
      );
    } finally {
      setLoading(false);
    }
  };

  const trainerOptions = trainers.map((t) => ({
    value: t.id,
    label: `${t.lastName} ${t.firstName}`,
  }));

  const clientOptions = clients.map((c) => ({
    value: c.id,
    label: `${c.lastName} ${c.firstName} — ${c.phone}`,
  }));

  const slotOptions = slots.map((s) => ({
    value: s.startTime,
    label: `${s.startTime} – ${s.endTime}`,
  }));

  const durationOptions = [
    { value: '30', label: '30 мин' },
    { value: '45', label: '45 мин' },
    { value: '60', label: '60 мин' },
    { value: '90', label: '90 мин' },
    { value: '120', label: '120 мин' },
  ];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Запись на ВПТ</DialogTitle>
          <DialogDescription>
            Вводная персональная тренировка
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 mt-4">
          {/* Client search */}
          <div>
            <Input
              label="Поиск клиента"
              placeholder="Имя или телефон (мин. 2 символа)..."
              value={clientSearch}
              onChange={(e) => {
                setClientSearch(e.target.value);
                setClientId('');
              }}
            />
            {loadingClients && (
              <p className="mt-1 text-xs text-[#6B7280]">Поиск...</p>
            )}
          </div>

          {clients.length > 0 && (
            <Select
              label="Клиент"
              placeholder="Выберите клиента"
              options={clientOptions}
              value={clientId}
              onChange={(e) => setClientId(e.target.value)}
            />
          )}

          {/* Trainer */}
          <Select
            label="Тренер"
            placeholder={loadingTrainers ? 'Загрузка...' : 'Выберите тренера'}
            options={trainerOptions}
            value={trainerId}
            onChange={(e) => setTrainerId(e.target.value)}
            disabled={loadingTrainers}
          />

          {/* Date */}
          <Input
            label="Дата"
            type="date"
            value={date}
            min={toLocalDate(new Date())}
            onChange={(e) => {
              setDate(e.target.value);
              setTime('');
            }}
          />

          {/* Time slot or manual */}
          {slots.length > 0 ? (
            <Select
              label="Время (свободные слоты)"
              placeholder={loadingSlots ? 'Загрузка...' : 'Выберите время'}
              options={slotOptions}
              value={time}
              onChange={(e) => setTime(e.target.value)}
              disabled={loadingSlots}
            />
          ) : (
            <Input
              label="Время"
              type="time"
              value={time}
              onChange={(e) => setTime(e.target.value)}
              placeholder={loadingSlots ? 'Загрузка слотов...' : ''}
            />
          )}

          {/* Duration */}
          <Select
            label="Длительность"
            options={durationOptions}
            value={duration}
            onChange={(e) => setDuration(e.target.value)}
          />

          {error && (
            <div className="rounded-lg bg-red-50 p-3 text-sm text-[#E53935]">
              {error}
            </div>
          )}
        </div>

        <DialogFooter className="mt-6">
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={loading}
          >
            Отмена
          </Button>
          <Button onClick={() => void handleSubmit()} disabled={loading}>
            {loading ? 'Создание...' : 'Записать'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function toLocalDate(d: Date): string {
  return d.toISOString().split('T')[0] ?? '';
}
