"use client";

import React, { useEffect, useMemo, useState } from 'react';
import { showToast } from '@/lib/toast';

type Status = 'not_started' | 'in_progress' | 'completed';

export type CourseFormValues = {
  title: string;
  description?: string;
  instructor?: string; // name string per backend schema
  duration?: string; // e.g., "6h", "30m", "1h 30m"
  thumbnail?: string; // public path / URL
  color?: string; // hex
  status?: Status;
};

type Props = {
  mode: 'create' | 'edit';
  courseId?: string;
  initial?: CourseFormValues;
  onDone?: (result: any) => void;
};

type Instructor = { id: string; name: string; email?: string };

export default function CourseForm({ mode, courseId, initial, onDone }: Props) {
  const [title, setTitle] = useState(initial?.title || '');
  const [description, setDescription] = useState(initial?.description || '');
  const [instructor, setInstructor] = useState(initial?.instructor || '');
  const [hours, setHours] = useState(() => {
    if (!initial?.duration) return 0;
    const hMatch = /(?<h>\d+)h/.exec(initial.duration || '');
    return hMatch ? Number(hMatch.groups?.h) : 0;
  });
  const [minutes, setMinutes] = useState(() => {
    if (!initial?.duration) return 0;
    const mMatch = /(?<m>\d+)m/.exec(initial.duration || '');
    return mMatch ? Number(mMatch.groups?.m) : 0;
  });
  const [color, setColor] = useState(initial?.color || '#3F51B5');
  const [status, setStatus] = useState<Status>(initial?.status || 'not_started');

  const [thumbPath, setThumbPath] = useState<string | undefined>(initial?.thumbnail || undefined);
  const [thumbPreview, setThumbPreview] = useState<string | undefined>(undefined);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);

  const [errors, setErrors] = useState<Record<string, string> | null>(null);

  const [instructorQuery, setInstructorQuery] = useState('');
  const [instructorOptions, setInstructorOptions] = useState<Instructor[]>([]);
  const [loadingInstructors, setLoadingInstructors] = useState(false);

  const durationString = useMemo(() => {
    const parts: string[] = [];
    if (hours && hours > 0) parts.push(`${hours}h`);
    if (minutes && minutes > 0) parts.push(`${minutes}m`);
    return parts.join(' ');
  }, [hours, minutes]);

  useEffect(() => {
    const ctrl = new AbortController();
    setLoadingInstructors(true);
    (async () => {
      try {
        const res = await fetch(`/api/instructors${instructorQuery ? `?q=${encodeURIComponent(instructorQuery)}` : ''}`, { signal: ctrl.signal });
        const json = await res.json();
        setInstructorOptions(json?.items || []);
      } catch {
        // ignore
      } finally {
        setLoadingInstructors(false);
      }
    })();
    return () => ctrl.abort();
  }, [instructorQuery]);

  function validate(): Record<string, string> {
    const errs: Record<string, string> = {};
    if (!title || title.trim().length < 3) errs.title = 'Judul minimal 3 karakter';
    if (!instructor || instructor.trim().length < 3) errs.instructor = 'Instruktur wajib dipilih';
    if (!durationString) errs.duration = 'Durasi wajib';
    else {
      const ok = /^(\d+h|\d+m|\d+h\s\d+m)$/.test(durationString);
      if (!ok) errs.duration = 'Durasi harus format seperti 6h, 30m, atau 1h 30m';
    }
    if (!thumbPath) errs.thumbnail = 'Thumbnail wajib';
    if (color) {
      const ok = /^#([A-Fa-f0-9]{6})$/.test(color.trim());
      if (!ok) errs.color = 'Warna harus hex contoh #FF9800';
    }
    if (status && !['not_started', 'in_progress', 'completed'].includes(status)) {
      errs.status = 'Status tidak valid';
    }
    return errs;
  }

  async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    setUploadError(null);
    if (!file) return;
    const previewUrl = URL.createObjectURL(file);
    setThumbPreview(previewUrl);
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append('file', file);
      const res = await fetch('/api/uploads', { method: 'POST', body: fd });
      const json = await res.json();
      if (!res.ok) {
        const msg = json?.error || 'Upload gagal';
        setUploadError(String(msg));
        showToast(String(msg), 'error');
        return;
      }
      setThumbPath(json?.path);
      showToast('Thumbnail berhasil diunggah', 'success');
    } catch (err: any) {
      const msg = err?.message || 'Upload gagal';
      setUploadError(String(msg));
      showToast(String(msg), 'error');
    } finally {
      setUploading(false);
    }
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    const errs = validate();
    if (Object.keys(errs).length > 0) {
      setErrors(errs);
      showToast('Periksa kembali input Anda', 'warning');
      return;
    }
    setErrors(null);

    const payload: CourseFormValues = {
      title: title.trim(),
      description: description || '',
      instructor: instructor.trim(),
      duration: durationString,
      thumbnail: thumbPath,
      color,
      status,
    };

    try {
      let res: Response;
      let json: any;
      if (mode === 'create') {
        res = await fetch('/api/courses', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        });
      } else {
        res = await fetch(`/api/courses/${encodeURIComponent(String(courseId))}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        });
      }
      json = await res.json().catch(() => null);
      if (!res.ok) {
        const msg = json?.error || 'Gagal menyimpan kursus';
        showToast(String(msg), 'error');
        setErrors({ general: String(msg) });
        return;
      }
      showToast(mode === 'create' ? 'Kursus berhasil dibuat' : 'Perubahan berhasil disimpan', 'success');
      onDone?.(json);
    } catch (err: any) {
      const msg = err?.message || 'Gagal menyimpan kursus';
      showToast(String(msg), 'error');
      setErrors({ general: String(msg) });
    }
  }

  return (
    <form onSubmit={handleSubmit} className="bg-white rounded-xl shadow-sm border border-gray-100 p-6 space-y-4 max-w-2xl">
      {errors && (
        <div className="p-4 bg-yellow-50 text-yellow-700 border border-yellow-200 rounded-lg">
          <ul className="list-disc ml-5 text-sm">
            {Object.entries(errors).map(([k, v]) => (
              <li key={k}>{v}</li>
            ))}
          </ul>
        </div>
      )}

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">Judul</label>
        <input
          type="text"
          value={title}
          onChange={e => setTitle(e.target.value)}
          className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
          required
        />
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">Deskripsi</label>
        <textarea
          value={description}
          onChange={e => setDescription(e.target.value)}
          rows={4}
          className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
        />
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">Instruktur</label>
        <div className="flex items-center gap-2 mb-2">
          <input
            type="text"
            placeholder="Cari instruktur..."
            value={instructorQuery}
            onChange={e => setInstructorQuery(e.target.value)}
            className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
          />
          {loadingInstructors && <span className="text-sm text-gray-500">Memuat...</span>}
        </div>
        <select
          value={instructor}
          onChange={e => setInstructor(e.target.value)}
          className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
          required
        >
          <option value="" disabled>Pilih instruktur</option>
          {instructorOptions.map((i) => (
            <option key={i.id} value={i.name}>{i.name}</option>
          ))}
        </select>
        {errors?.instructor && <p className="text-xs text-red-600 mt-1">{errors.instructor}</p>}
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Durasi</label>
          <div className="flex items-center gap-2">
            <div className="flex flex-col">
              <input type="number" min={0} max={24} value={hours} onChange={e => setHours(Number(e.target.value))} className="w-24 px-3 py-2 border border-gray-300 rounded-lg" />
              <span className="text-xs text-gray-500">Jam (0–24)</span>
            </div>
            <div className="flex flex-col">
              <input type="number" min={0} max={59} value={minutes} onChange={e => setMinutes(Number(e.target.value))} className="w-24 px-3 py-2 border border-gray-300 rounded-lg" />
              <span className="text-xs text-gray-500">Menit (0–59)</span>
            </div>
          </div>
          {errors?.duration && <p className="text-xs text-red-600 mt-1">{errors.duration}</p>}
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Warna Tema</label>
          <div className="flex items-center gap-3">
            <input type="color" value={color} onChange={e => setColor(e.target.value)} className="h-10 w-16 p-1 border rounded" />
            <input type="text" value={color} onChange={e => setColor(e.target.value)} className="flex-1 px-3 py-2 border border-gray-300 rounded-lg" />
          </div>
          {errors?.color && <p className="text-xs text-red-600 mt-1">{errors.color}</p>}
        </div>
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">Thumbnail</label>
        <div className="flex items-center gap-4">
          <input type="file" accept="image/*" onChange={handleFileChange} className="flex-1" />
          {uploading && <span className="text-sm text-gray-500">Mengunggah...</span>}
        </div>
        {(thumbPreview || thumbPath) && (
          <div className="mt-3">
            <img src={thumbPreview || thumbPath} alt="preview" className="w-48 h-28 object-cover rounded border" />
            {thumbPath && <p className="text-xs text-gray-500 mt-1">Disimpan: {thumbPath}</p>}
          </div>
        )}
        {uploadError && <p className="text-xs text-red-600 mt-1">{uploadError}</p>}
        {errors?.thumbnail && <p className="text-xs text-red-600 mt-1">{errors.thumbnail}</p>}
      </div>

      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">Status Kursus</label>
        <select value={status} onChange={e => setStatus(e.target.value as Status)} className="w-full px-3 py-2 border border-gray-300 rounded-lg">
          <option value="not_started">Belum Mulai</option>
          <option value="in_progress">Berlangsung</option>
          <option value="completed">Selesai</option>
        </select>
      </div>

      <div className="flex items-center justify-end gap-2">
        <button type="submit" className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
          {mode === 'create' ? 'Buat Kursus' : 'Simpan'}
        </button>
      </div>
    </form>
  );
}