'use client';

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { createViharSchema, type CreateViharInput, type Gender } from '@vihar/shared';
import { api, ApiError } from '@/lib/api';
import { LocationPicker } from '@/components/locations/location-picker';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { ComboboxAddNew } from '@/components/ui/combobox-add-new';

// ---- Types ----------------------------------------------------------------

interface Samuday { samudayId: number; name: string }
interface Saint {
  saintId: number;
  name: string;
  honorific: string | null;
  gender: Gender;
  samudayId: number | null;
  samuday?: { samudayId: number; name: string } | null;
}
interface RouteInfo { distanceMeters: number; durationSeconds: number }

// Display label for saint gender. UI uses the Jain ascetic terminology;
// the DB enum stays male/female.
function saintTypeLabel(g: Gender): 'Sadhu' | 'Sadhvi' {
  return g === 'male' ? 'Sadhu' : 'Sadhvi';
}

// ---- Helpers --------------------------------------------------------------

function tomorrow(): string {
  const d = new Date();
  d.setDate(d.getDate() + 1);
  return d.toISOString().slice(0, 10);
}

function defaultTime(): string {
  return new Date().getHours() < 12 ? '05:30' : '17:00';
}

function fmtDistance(r: RouteInfo): string {
  const km = (r.distanceMeters / 1000).toFixed(1);
  const mins = Math.round(r.durationSeconds / 60);
  const h = Math.floor(mins / 60);
  const m = mins % 60;
  const dur = h > 0 ? `${h}h ${m}m` : `${m}m`;
  return `~${km} km · ~${dur}`;
}

// ---- Stepper --------------------------------------------------------------

function Stepper({ value, onChange, min = 0, max = 100 }: {
  value: number; onChange: (n: number) => void; min?: number; max?: number;
}) {
  return (
    <div className="flex items-center gap-2">
      <button
        type="button"
        onClick={() => onChange(Math.max(min, value - 1))}
        disabled={value <= min}
        className="flex h-8 w-8 items-center justify-center rounded-full border border-paper-300 text-ink transition-colors hover:bg-paper-200 disabled:opacity-30"
      >−</button>
      <span className="w-6 text-center text-sm font-medium tabular-nums">{value}</span>
      <button
        type="button"
        onClick={() => onChange(Math.min(max, value + 1))}
        disabled={value >= max}
        className="flex h-8 w-8 items-center justify-center rounded-full border border-paper-300 text-ink transition-colors hover:bg-paper-200 disabled:opacity-30"
      >+</button>
    </div>
  );
}

// ---- Toggle ---------------------------------------------------------------

function Toggle({ checked, onChange, label }: { checked: boolean; onChange: (v: boolean) => void; label: string }) {
  return (
    <button
      type="button"
      onClick={() => onChange(!checked)}
      className="flex items-center justify-between py-1 w-full"
    >
      <span className="text-sm text-ink">{label}</span>
      <span className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${checked ? 'bg-saffron' : 'bg-paper-300'}`}>
        <span className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${checked ? 'translate-x-6' : 'translate-x-1'}`} />
      </span>
    </button>
  );
}

// ---- Page -----------------------------------------------------------------

export default function NewViharPage() {
  const router = useRouter();
  const [samudayList, setSamudayList] = useState<Samuday[]>([]);
  const [saintList, setSaintList] = useState<Saint[]>([]);
  const [pickedSaintId, setPickedSaintId] = useState<number | null>(null);
  const [addSaintQuery, setAddSaintQuery] = useState<string | null>(null);
  const [addSamudayQuery, setAddSamudayQuery] = useState<string | null>(null);
  const [route, setRoute] = useState<RouteInfo | null>(null);
  const [routeError, setRouteError] = useState(false);
  const [submitError, setSubmitError] = useState('');

  const {
    register,
    handleSubmit,
    control,
    watch,
    setValue,
    formState: { errors, isSubmitting },
  } = useForm<CreateViharInput>({
    resolver: zodResolver(createViharSchema),
    defaultValues: {
      viharDate: tomorrow(),
      plannedStartTime: defaultTime(),
      sadhujiCount: 0,
      sadhvijiCount: 0,
      otherCount: 0,
      headSaintHonorific: '',
      headSaintName: '',
      templeDarshan: false,
      updhi: false,
      remarks: '',
      samudayId: null,
      departureLocationId: undefined as unknown as number,
      arrivalLocationId: undefined as unknown as number,
    },
  });

  const departureId = watch('departureLocationId');
  const arrivalId = watch('arrivalLocationId');

  // Load samuday + saint lists once
  useEffect(() => {
    api.get<Samuday[]>('/api/samuday').then(setSamudayList).catch(() => {});
    api.get<Saint[]>('/api/saints').then(setSaintList).catch(() => {});
  }, []);

  function applySaint(s: Saint) {
    setPickedSaintId(s.saintId);
    setValue('headSaintName', s.name, { shouldValidate: true });
    setValue('headSaintHonorific', s.honorific ?? '', { shouldValidate: true });
    if (s.samudayId) setValue('samudayId', s.samudayId, { shouldValidate: true });
  }

  function clearSaint() {
    setPickedSaintId(null);
    setValue('headSaintName', '', { shouldValidate: true });
    setValue('headSaintHonorific', '', { shouldValidate: true });
  }

  // Fetch route when both locations are set
  useEffect(() => {
    if (!departureId || !arrivalId || departureId === arrivalId) {
      setRoute(null);
      return;
    }
    setRouteError(false);
    api.get<RouteInfo>('/api/routes/walking', { query: { from: departureId, to: arrivalId } })
      .then(setRoute)
      .catch(() => { setRoute(null); setRouteError(true); });
  }, [departureId, arrivalId]);

  async function onSubmit(data: CreateViharInput) {
    setSubmitError('');
    try {
      const vihar = await api.post<{ viharId: number }>('/api/vihars', data);
      router.push(`/captain/vihars/${vihar.viharId}`);
    } catch (e) {
      setSubmitError(e instanceof ApiError ? e.message : 'Failed to create vihar');
    }
  }

  return (
    <div className="space-y-5 pb-24">
      <div>
        <h1 className="font-display text-2xl font-semibold text-ink">New Vihar</h1>
        <p className="mt-0.5 text-sm text-ink-300">Volunteers can be allocated later from the vihar detail page.</p>
      </div>

      <form onSubmit={handleSubmit(onSubmit)} noValidate className="space-y-4">

        {/* ---- When ---- */}
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-base">When</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="mb-1.5 block text-sm">Date</Label>
                <Input type="date" {...register('viharDate')} className="w-full" />
                {errors.viharDate && <p className="mt-1 text-xs text-rust">{errors.viharDate.message}</p>}
              </div>
              <div>
                <Label className="mb-1.5 block text-sm">Time</Label>
                <Input type="time" {...register('plannedStartTime')} className="w-full" />
                {errors.plannedStartTime && <p className="mt-1 text-xs text-rust">{errors.plannedStartTime.message}</p>}
              </div>
            </div>
          </CardContent>
        </Card>

        {/* ---- Who ---- */}
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-base">Who</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* Counts */}
            <div className="grid grid-cols-3 gap-3">
              {([
                { label: 'Sadhuji', field: 'sadhujiCount' },
                { label: 'Sadhviji', field: 'sadhvijiCount' },
                { label: 'Others', field: 'otherCount' },
              ] as const).map(({ label, field }) => (
                <div key={field} className="flex flex-col items-center gap-1">
                  <Label className="text-xs">{label}</Label>
                  <Controller
                    name={field}
                    control={control}
                    render={({ field: f }) => (
                      <Stepper value={f.value} onChange={f.onChange} />
                    )}
                  />
                </div>
              ))}
            </div>

            {/* Head Sadhu / Sadhvi — searchable; "+ Add" creates inline */}
            <div>
              <Label className="mb-1.5 block text-sm">Head Sadhu / Sadhvi <span className="text-rust">*</span></Label>
              <ComboboxAddNew
                value={pickedSaintId}
                items={saintList.map((s) => ({
                  id: s.saintId,
                  label: s.honorific ? `${s.honorific} ${s.name}` : s.name,
                  subtitle: [saintTypeLabel(s.gender), s.samuday?.name].filter(Boolean).join(' · '),
                }))}
                onChange={(id, _item) => {
                  if (id === null) {
                    clearSaint();
                  } else {
                    const s = saintList.find((x) => x.saintId === id);
                    if (s) applySaint(s);
                  }
                }}
                onAddNew={(q) => setAddSaintQuery(q)}
                placeholder="Search Sadhu / Sadhvi or add new…"
                emptyHint="No entries yet. Type a name and tap + Add."
              />
              {errors.headSaintName && <p className="mt-1 text-xs text-rust">Pick or add a Sadhu / Sadhvi</p>}
            </div>

            {/* Samuday — searchable; "+ Add" creates a new samuday */}
            <div>
              <Label className="mb-1.5 block text-sm">Samuday</Label>
              <Controller
                name="samudayId"
                control={control}
                render={({ field: f }) => (
                  <ComboboxAddNew
                    value={f.value ?? null}
                    items={samudayList.map((s) => ({ id: s.samudayId, label: s.name }))}
                    onChange={(id) => f.onChange(id)}
                    onAddNew={(q) => setAddSamudayQuery(q)}
                    placeholder="Select samuday or add new…"
                  />
                )}
              />
            </div>
          </CardContent>
        </Card>

        {/* Add-saint modal */}
        {addSaintQuery !== null && (
          <AddSaintModal
            initialName={addSaintQuery}
            samudayList={samudayList}
            onCancel={() => setAddSaintQuery(null)}
            onCreated={(s) => {
              setSaintList((prev) => [...prev, s]);
              applySaint(s);
              setAddSaintQuery(null);
            }}
          />
        )}

        {/* Add-samuday modal */}
        {addSamudayQuery !== null && (
          <AddSamudayModal
            initialName={addSamudayQuery}
            onCancel={() => setAddSamudayQuery(null)}
            onCreated={(s) => {
              setSamudayList((prev) => [...prev, s]);
              setValue('samudayId', s.samudayId, { shouldValidate: true });
              setAddSamudayQuery(null);
            }}
          />
        )}

        {/* ---- Route ---- */}
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-base">Route</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <Controller
              name="departureLocationId"
              control={control}
              render={({ field: f }) => (
                <LocationPicker
                  label="Departure"
                  value={f.value ?? null}
                  onChange={(id) => f.onChange(id)}
                  error={errors.departureLocationId?.message}
                />
              )}
            />
            <Controller
              name="arrivalLocationId"
              control={control}
              render={({ field: f }) => (
                <LocationPicker
                  label="Arrival"
                  value={f.value ?? null}
                  onChange={(id) => f.onChange(id)}
                  error={errors.arrivalLocationId?.message}
                />
              )}
            />

            {/* Route summary */}
            {route && (
              <div className="rounded-md bg-saffron-50 px-3 py-2 text-sm text-saffron-700">
                Walking distance: {fmtDistance(route)}
              </div>
            )}
            {routeError && (
              <p className="text-xs text-ink-300">Distance will be calculated later.</p>
            )}
            {/* departure == arrival */}
            {departureId && arrivalId && departureId === arrivalId && (
              <p className="text-xs text-rust">Departure and arrival must be different.</p>
            )}
          </CardContent>
        </Card>

        {/* ---- Options ---- */}
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-base">Options</CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <Controller
              name="templeDarshan"
              control={control}
              render={({ field: f }) => (
                <Toggle checked={f.value} onChange={f.onChange} label="Temple Darshan" />
              )}
            />
            <div className="h-px bg-paper-200" />
            <Controller
              name="updhi"
              control={control}
              render={({ field: f }) => (
                <Toggle checked={f.value} onChange={f.onChange} label="Updhi" />
              )}
            />
            <div className="h-px bg-paper-200" />
            <div>
              <Label className="mb-1.5 block text-sm">Remarks</Label>
              <textarea
                {...register('remarks')}
                rows={3}
                placeholder="Any special instructions…"
                className="w-full rounded-md border border-paper-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-saffron"
              />
              {errors.remarks && <p className="mt-1 text-xs text-rust">{errors.remarks.message}</p>}
            </div>
          </CardContent>
        </Card>

        {submitError && (
          <p className="rounded-md bg-red-50 px-3 py-2 text-sm text-rust">{submitError}</p>
        )}

        {/* ---- Actions ---- */}
        <div className="flex gap-3">
          <Button
            type="button"
            variant="outline"
            className="flex-1"
            onClick={() => router.push('/captain')}
          >
            Cancel
          </Button>
          <Button
            type="submit"
            className="flex-1"
            disabled={isSubmitting || (!!departureId && !!arrivalId && departureId === arrivalId)}
          >
            {isSubmitting ? 'Saving…' : 'Save Vihar'}
          </Button>
        </div>

      </form>
    </div>
  );
}

// ---- Add-saint modal -----------------------------------------------------

function AddSaintModal({
  initialName,
  samudayList,
  onCancel,
  onCreated,
}: {
  initialName: string;
  samudayList: Samuday[];
  onCancel: () => void;
  onCreated: (s: Saint) => void;
}) {
  const [name, setName] = useState(initialName);
  const [honorific, setHonorific] = useState('');
  const [gender, setGender] = useState<Gender | ''>('');
  const [samudayId, setSamudayId] = useState<number | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  async function submit() {
    if (!name.trim() || !gender) {
      setError('Name and type (Sadhu/Sadhvi) are required');
      return;
    }
    setBusy(true);
    setError('');
    try {
      const created = await api.post<Saint>('/api/saints', {
        name: name.trim(),
        honorific: honorific.trim() || undefined,
        gender,
        samudayId,
      });
      onCreated(created);
    } catch (e) {
      setError(e instanceof ApiError ? e.message : 'Failed to add saint');
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="fixed inset-0 z-40 flex items-end justify-center bg-black/40 sm:items-center" onClick={onCancel}>
      <div
        className="w-full max-w-md space-y-3 rounded-t-xl bg-white p-4 shadow-xl sm:rounded-xl"
        onClick={(e) => e.stopPropagation()}
      >
        <h2 className="font-display text-lg font-semibold text-ink">Add Sadhu / Sadhvi</h2>

        <div>
          <Label className="mb-1 block text-sm">Name <span className="text-rust">*</span></Label>
          <Input value={name} onChange={(e) => setName(e.target.value)} autoFocus />
        </div>
        <div>
          <Label className="mb-1 block text-sm">Honorific</Label>
          <Input value={honorific} onChange={(e) => setHonorific(e.target.value)} placeholder="P.P.A." />
        </div>
        <div>
          <Label className="mb-1 block text-sm">Type <span className="text-rust">*</span></Label>
          <div className="flex gap-2">
            {([
              { value: 'male' as const, label: 'Sadhu' },
              { value: 'female' as const, label: 'Sadhvi' },
            ]).map((opt) => (
              <button
                key={opt.value}
                type="button"
                onClick={() => setGender(opt.value)}
                className={`flex-1 rounded-md border px-3 py-2 text-sm font-medium transition-colors ${
                  gender === opt.value
                    ? 'border-saffron bg-saffron/10 text-saffron-700'
                    : 'border-paper-300 bg-white text-ink-400 hover:bg-paper-50'
                }`}
              >
                {opt.label}
              </button>
            ))}
          </div>
        </div>
        <div>
          <Label className="mb-1 block text-sm">Samuday</Label>
          <select
            value={samudayId ?? ''}
            onChange={(e) => setSamudayId(e.target.value ? Number(e.target.value) : null)}
            className="w-full rounded-md border border-paper-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-saffron"
          >
            <option value="">— none —</option>
            {samudayList.map((s) => (
              <option key={s.samudayId} value={s.samudayId}>{s.name}</option>
            ))}
          </select>
        </div>

        {error && <p className="rounded-md bg-red-50 px-3 py-2 text-xs text-rust">{error}</p>}

        <div className="flex gap-2 pt-1">
          <Button variant="outline" className="flex-1" onClick={onCancel} disabled={busy}>Cancel</Button>
          <Button className="flex-1" onClick={submit} disabled={busy}>
            {busy ? 'Saving…' : 'Add'}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ---- Add-samuday modal ---------------------------------------------------

function AddSamudayModal({
  initialName,
  onCancel,
  onCreated,
}: {
  initialName: string;
  onCancel: () => void;
  onCreated: (s: Samuday) => void;
}) {
  const [name, setName] = useState(initialName);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  async function submit() {
    if (!name.trim()) {
      setError('Name is required');
      return;
    }
    setBusy(true);
    setError('');
    try {
      const created = await api.post<Samuday>('/api/samuday', { name: name.trim() });
      onCreated(created);
    } catch (e) {
      setError(e instanceof ApiError ? e.message : 'Failed to add samuday');
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="fixed inset-0 z-40 flex items-end justify-center bg-black/40 sm:items-center" onClick={onCancel}>
      <div
        className="w-full max-w-md space-y-3 rounded-t-xl bg-white p-4 shadow-xl sm:rounded-xl"
        onClick={(e) => e.stopPropagation()}
      >
        <h2 className="font-display text-lg font-semibold text-ink">Add Samuday</h2>
        <div>
          <Label className="mb-1 block text-sm">Name <span className="text-rust">*</span></Label>
          <Input value={name} onChange={(e) => setName(e.target.value)} autoFocus />
        </div>
        {error && <p className="rounded-md bg-red-50 px-3 py-2 text-xs text-rust">{error}</p>}
        <div className="flex gap-2 pt-1">
          <Button variant="outline" className="flex-1" onClick={onCancel} disabled={busy}>Cancel</Button>
          <Button className="flex-1" onClick={submit} disabled={busy}>
            {busy ? 'Saving…' : 'Add Samuday'}
          </Button>
        </div>
      </div>
    </div>
  );
}
