'use client';

import { useState, useMemo, useCallback, useRef } from 'react';
import {
  Copy, Check, BookmarkPlus, Clock, Trash2, ChevronRight,
  AlertCircle, CalendarClock,
} from 'lucide-react';
import { toast } from 'sonner';
import { cn } from '@/lib/utils/cn';
import { cardBtn } from '@/lib/utils/styles';
import { MobileTabs } from '@/components/ui/mobile-tabs';
import { CronFieldEditor } from './CronFieldEditor';
import { CronPresets } from './CronPresets';
import { useCronStore } from '@/lib/cron/store';
import {
  FIELD_CONFIGS,
  splitCronFields,
  buildCronExpression,
  describeCronExpression,
  validateCronExpression,
  getNextOccurrences,
  type FieldType,
  type CronFields,
} from '@/lib/cron/cron-engine';

const FIELD_ORDER: FieldType[] = ['minute', 'hour', 'dom', 'month', 'dow'];

function getFieldValue(fields: CronFields, type: FieldType): string {
  switch (type) {
    case 'minute': return fields.minute;
    case 'hour':   return fields.hour;
    case 'dom':    return fields.dom;
    case 'month':  return fields.month;
    case 'dow':    return fields.dow;
    case 'second': return fields.second ?? '*';
  }
}

function formatOccurrence(d: Date): { relative: string; absolute: string; dow: string } {
  const now      = new Date();
  const diffMs   = d.getTime() - now.getTime();
  const diffMins = Math.round(diffMs / 60_000);
  const diffH    = Math.round(diffMs / 3_600_000);
  const diffD    = Math.round(diffMs / 86_400_000);

  let relative: string;
  if (diffMins < 60)   relative = `in ${diffMins}m`;
  else if (diffH < 24) relative = `in ${diffH}h`;
  else if (diffD === 1) relative = 'tomorrow';
  else                 relative = `in ${diffD}d`;

  const absolute = d.toLocaleString('en-US', {
    month: 'short', day: 'numeric',
    hour: 'numeric', minute: '2-digit', hour12: true,
  });
  const dow = d.toLocaleDateString('en-US', { weekday: 'short' });
  return { relative, absolute, dow };
}

// ── Schedule list ─────────────────────────────────────────────────────────────

function ScheduleList({ schedule, isValid }: { schedule: Date[]; isValid: boolean }) {
  if (!isValid) return (
    <p className="text-xs text-muted-foreground/40 text-center py-8 font-mono">
      Fix the expression to see upcoming runs
    </p>
  );
  if (schedule.length === 0) return (
    <p className="text-xs text-muted-foreground/40 text-center py-8 font-mono">
      No occurrences in the next 5 years
    </p>
  );
  return (
    <div className="flex flex-col">
      {schedule.map((d, i) => {
        const { relative, absolute, dow } = formatOccurrence(d);
        const isFirst = i === 0;
        return (
          <div
            key={i}
            className={cn(
              'flex items-center gap-2.5 py-2.5 border-b border-border/10 last:border-0',
            )}
          >
            <span className={cn(
              'font-mono text-[10px] px-1.5 py-0.5 rounded border shrink-0 w-[36px] text-center',
              isFirst
                ? 'bg-primary/20 text-primary border-primary/30'
                : 'bg-muted/15 text-muted-foreground/50 border-border/10',
            )}>
              {dow}
            </span>
            <span className={cn(
              'text-xs font-mono flex-1',
              isFirst ? 'text-foreground font-medium' : 'text-muted-foreground',
            )}>
              {absolute}
            </span>
            <span className="text-[10px] font-mono text-muted-foreground/35 shrink-0">
              {relative}
            </span>
          </div>
        );
      })}
    </div>
  );
}

// ── Component ─────────────────────────────────────────────────────────────────

export function CronEditor() {
  const { expression, setExpression, addToHistory, history, removeFromHistory, clearHistory } =
    useCronStore();

  const [activeField, setActiveField] = useState<FieldType>('minute');
  const [mobileTab, setMobileTab]     = useState<'editor' | 'preview'>('editor');
  const [copied, setCopied]           = useState(false);
  const [editingRaw, setEditingRaw]   = useState(false);
  const [rawExpr, setRawExpr]         = useState('');
  const rawInputRef = useRef<HTMLInputElement>(null);

  const isValid     = useMemo(() => validateCronExpression(expression).valid, [expression]);
  const fields      = useMemo(() => splitCronFields(expression), [expression]);
  const description = useMemo(() => describeCronExpression(expression), [expression]);
  const schedule    = useMemo(
    () => (isValid ? getNextOccurrences(expression, 10) : []),
    [expression, isValid],
  );

  const handleFieldChange = useCallback(
    (type: FieldType, value: string) => {
      if (!fields) return;
      const updated: CronFields = { ...fields, [type]: value };
      setExpression(buildCronExpression(updated));
    },
    [fields, setExpression],
  );

  const handleCopy = async () => {
    await navigator.clipboard.writeText(expression);
    setCopied(true);
    toast.success('Copied to clipboard');
    setTimeout(() => setCopied(false), 2000);
  };

  const handleSave = () => {
    addToHistory(expression);
    toast.success('Saved to history');
  };

  const handleRawKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      if (validateCronExpression(rawExpr).valid) setExpression(rawExpr);
      setEditingRaw(false);
    }
    if (e.key === 'Escape') setEditingRaw(false);
  };

  const startEditRaw = () => {
    setRawExpr(expression);
    setEditingRaw(true);
    setTimeout(() => rawInputRef.current?.focus(), 0);
  };

  // ── Expression bar (rendered inside right panel) ──────────────────────────
  const expressionBar = (
    <div className="glass rounded-xl border border-border/40 p-4">
      {/* Row 1: Field chips + actions */}
      <div className="flex items-center gap-1.5 flex-wrap mb-3">
        {FIELD_ORDER.map((type) => {
          const active = activeField === type;
          const fValue = fields ? getFieldValue(fields, type) : '*';
          return (
            <button
              key={type}
              onClick={() => { setActiveField(type); setMobileTab('editor'); }}
              className={cn(
                'flex items-center gap-1.5 px-2 py-1 rounded-md border transition-all',
                active
                  ? 'bg-primary/15 border-primary/50 shadow-[0_0_8px_rgba(139,92,246,0.2)]'
                  : 'glass border-border/25 hover:border-primary/30 hover:bg-primary/5',
              )}
            >
              <span className={cn(
                'text-[8px] font-mono uppercase tracking-[0.1em]',
                active ? 'text-primary/60' : 'text-muted-foreground/40',
              )}>
                {FIELD_CONFIGS[type].shortLabel}
              </span>
              <span className={cn(
                'font-mono text-[10px] font-semibold',
                active ? 'text-primary' : fValue === '*' ? 'text-muted-foreground/50' : 'text-foreground',
              )}>
                {fValue}
              </span>
            </button>
          );
        })}

        <div className="ml-auto flex items-center gap-1.5">
          <button onClick={handleCopy} className={cardBtn}>
            {copied
              ? <><Check className="w-3 h-3" /> Copied</>
              : <><Copy className="w-3 h-3" /> Copy</>}
          </button>
          <button onClick={handleSave} className={cardBtn}>
            <BookmarkPlus className="w-3 h-3" /> Save
          </button>
        </div>
      </div>

      {/* Row 2: Expression + description (stacked on mobile, inline on lg) */}
      <div className="flex flex-col gap-1 min-w-0">
        <div
          className={cn(
            'cursor-text font-mono text-sm tracking-[0.15em] rounded px-1 -mx-1 py-0.5 transition-colors w-full',
            !editingRaw && 'hover:bg-white/3',
            !isValid && !editingRaw && 'text-destructive/70',
          )}
          onClick={!editingRaw ? startEditRaw : undefined}
        >
          {editingRaw ? (
            <input
              ref={rawInputRef}
              value={rawExpr}
              onChange={(e) => setRawExpr(e.target.value)}
              onKeyDown={handleRawKey}
              onBlur={() => setEditingRaw(false)}
              className={cn(
                'w-full bg-transparent font-mono text-sm tracking-[0.15em] focus:outline-none',
                validateCronExpression(rawExpr).valid ? 'text-foreground' : 'text-destructive/80',
              )}
            />
          ) : (
            expression
          )}
        </div>

        <div className="flex items-center gap-1.5 min-w-0">
          {isValid
            ? <CalendarClock className="w-3 h-3 text-muted-foreground/30 shrink-0" />
            : <AlertCircle className="w-3 h-3 text-destructive/50 shrink-0" />}
          <p className={cn(
            'text-xs truncate',
            isValid ? 'text-muted-foreground' : 'text-destructive/60',
          )}>
            {description}
          </p>
        </div>
      </div>

      {/* Row 3: Presets select */}
      <div className="mt-3 pt-3 border-t border-border/10">
        <CronPresets onSelect={(expr) => setExpression(expr)} current={expression} />
      </div>
    </div>
  );

  return (
    <div className="flex flex-col gap-4 animate-fade-in">

      {/* ── Mobile tabs ─────────────────────────────────────────────────── */}
      <MobileTabs
        tabs={[{ value: 'editor', label: 'Editor' }, { value: 'preview', label: 'Preview' }]}
        active={mobileTab}
        onChange={(v) => setMobileTab(v as 'editor' | 'preview')}
      />

      {/* ── Main content ────────────────────────────────────────────────── */}
      <div className="grid lg:grid-cols-5 gap-4">

        {/* Left: Field editor + Presets ──────────────────────────────── */}
        <div className={cn(
          'lg:col-span-3 flex flex-col gap-4',
          mobileTab === 'preview' && 'hidden lg:flex',
        )}>
          {/* Field selector tabs */}
          <div className="flex glass rounded-lg p-0.5 gap-0.5">
            {FIELD_ORDER.map((type) => (
              <button
                key={type}
                onClick={() => setActiveField(type)}
                className={cn(
                  'flex-1 flex items-center justify-center gap-1.5 py-1.5 rounded-md text-xs font-medium transition-all',
                  activeField === type
                    ? 'bg-primary text-primary-foreground shadow-sm'
                    : 'text-muted-foreground hover:text-foreground'
                )}
              >
                {FIELD_CONFIGS[type].shortLabel}
              </button>
            ))}
          </div>

          {/* Field editor panel */}
          <div className="glass rounded-xl p-5 border border-border/40">
            {fields ? (
              <CronFieldEditor
                fieldType={activeField}
                value={getFieldValue(fields, activeField)}
                onChange={(v) => handleFieldChange(activeField, v)}
              />
            ) : (
              <p className="text-sm text-muted-foreground text-center py-8">
                Invalid expression — fix it above to edit fields
              </p>
            )}
          </div>

          {/* Saved history */}
          {history.length > 0 && (
            <div className="glass rounded-xl p-4 border border-border/40">
              <div className="flex items-center justify-between mb-3">
                <span className="text-[9px] font-mono text-muted-foreground/40 uppercase tracking-widest">
                  Saved
                </span>
                <button onClick={clearHistory} className={cardBtn}>
                  <Trash2 className="w-2.5 h-2.5" /> Clear
                </button>
              </div>
              <div className="flex flex-col gap-1">
                {history.slice(0, 8).map((entry) => (
                  <div key={entry.id} className="flex items-center gap-2 group">
                    <button
                      onClick={() => setExpression(entry.expression)}
                      className={cn(
                        'flex-1 flex items-center gap-2 px-3 py-1.5 rounded-lg border transition-all text-left',
                        entry.expression === expression
                          ? 'bg-primary/10 border-primary/30 text-primary'
                          : 'glass border-border/20 text-muted-foreground hover:border-primary/30 hover:text-foreground',
                      )}
                    >
                      {entry.expression === expression && <ChevronRight className="w-3 h-3 shrink-0" />}
                      <span className="font-mono text-xs truncate">{entry.expression}</span>
                    </button>
                    <button
                      onClick={() => removeFromHistory(entry.id)}
                      className="opacity-0 group-hover:opacity-100 w-6 h-6 flex items-center justify-center text-muted-foreground/40 hover:text-destructive transition-all rounded"
                    >
                      ×
                    </button>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>

        {/* Right: Expression bar + Schedule preview ───────────────────── */}
        <div className={cn(
          'lg:col-span-2 flex flex-col gap-4',
          mobileTab === 'editor' && 'hidden lg:flex',
        )}>
          {expressionBar}

          <div className="glass rounded-xl p-4 border border-border/40">
            <div className="flex items-center gap-2 mb-3">
              <Clock className="w-3.5 h-3.5 text-muted-foreground/40" />
              <span className="text-[9px] font-mono text-muted-foreground/50 uppercase tracking-widest">
                Next Occurrences
              </span>
            </div>
            <ScheduleList schedule={schedule} isValid={isValid} />
          </div>
        </div>

      </div>
    </div>
  );
}
