import React, { useMemo, useRef, useState } from 'react';
import { Pencil, Settings2 } from 'lucide-react';
import { toast } from 'sonner';
import { cn, fmt, fmtDate } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { StatusBadge } from './StatusBadge';
import { api } from '@/api.js';

const MONTHS = [
  'January','February','March','April','May','June',
  'July','August','September','October','November','December',
];

const ROW_STATUS_CLS = {
  paid:      'bg-emerald-500/[0.04]',
  autodraft: 'bg-sky-500/[0.04]',
  upcoming:  '',
  due_soon:  'bg-amber-400/[0.07]',
  late:      'bg-orange-400/[0.08]',
  missed:    'bg-red-400/[0.08]',
};

function paymentDateForTrackerMonth(year, month, dueDay) {
  const now = new Date();
  if (year === now.getFullYear() && month === now.getMonth() + 1) {
    return fmtDate(new Date().toISOString().slice(0, 10));
  }

  const daysInMonth = new Date(year, month, 0).getDate();
  const day = Number.isInteger(Number(dueDay))
    ? Math.min(Math.max(Number(dueDay), 1), daysInMonth)
    : 1;

  return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
}

function EditableCell({ row, field, threshold, defaultPaymentDate, refresh }) {
  const [editing, setEditing] = useState(false);
  const [value, setValue] = useState('');
  const inputRef = useRef(null);

  const displayVal = useMemo(() => {
    if (field === 'amount') {
      return row.total_paid > 0 ? fmt(row.total_paid) : '—';
    }
    return row.last_paid_date ? fmtDate(row.last_paid_date) : '—';
  }, [field, row]);

  const isEmpty = useMemo(() => {
    if (field === 'amount') return row.total_paid <= 0;
    return !row.last_paid_date;
  }, [field, row]);

  const mismatch = useMemo(() => {
    if (field === 'amount') {
      return row.total_paid > 0 && row.total_paid !== threshold;
    }
    return false;
  }, [field, row, threshold]);

  function startEdit() {
    if (editing) return;
    setValue(field === 'amount'
      ? (row.total_paid > 0 ? String(row.total_paid) : '')
      : (row.last_paid_date || ''));
    setEditing(true);
    setTimeout(() => { inputRef.current?.focus(); inputRef.current?.select(); }, 0);
  }

  async function commit() {
    setEditing(false);
    const val = value.trim();
    if (!val) return;
    try {
      if (row.payments && row.payments.length > 0) {
        const update = {};
        if (field === 'amount') update.amount    = parseFloat(val);
        if (field === 'date')   update.paid_date = val;
        await api.updatePayment(row.payments[0].id, update);
      } else {
        await api.createPayment({
          bill_id:   row.id,
          amount:    field === 'amount' ? parseFloat(val) : threshold,
          paid_date: field === 'date'   ? val             : defaultPaymentDate,
        });
      }
      toast.success('Saved');
      refresh();
    } catch (err) {
      toast.error(err.message);
    }
  }

  function onKeyDown(e) {
    if (e.key === 'Enter')  inputRef.current?.blur();
    if (e.key === 'Escape') { setValue(''); setEditing(false); }
  }

  if (editing) {
    return (
      <Input
        ref={inputRef}
        type={field === 'date' ? 'date' : 'number'}
        step={field === 'amount' ? '0.01' : undefined}
        min={field === 'amount' ? '0' : undefined}
        value={value}
        onChange={e => setValue(e.target.value)}
        onBlur={commit}
        onKeyDown={onKeyDown}
        className="h-7 w-28 text-right font-mono text-sm bg-background/80 border-border/60"
      />
    );
  }

  return (
    <span
      onClick={startEdit}
      title={`Click to edit ${field === 'amount' ? 'payment amount' : 'paid date'}`}
      className={cn(
        'cursor-pointer rounded-md px-1.5 py-0.5 text-sm font-mono',
        'transition-all duration-150 hover:bg-accent hover:ring-1 hover:ring-border',
        isEmpty   && 'text-muted-foreground',
        mismatch  && 'text-amber-500',
        !isEmpty  && !mismatch && 'text-emerald-500',
      )}
    >
      {displayVal}
    </span>
  );
}

export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year, month, refresh, index, onEditBill }) {
  const amountRef = useRef(null);
  
  const threshold = useMemo(() => row.actual_amount != null ? row.actual_amount : row.expected_amount, [row]);
  const defaultPaymentDate = useMemo(() => paymentDateForTrackerMonth(year, month, row.due_day), [year, month, row.due_day]);
  const isPaidByThreshold = useMemo(() => row.total_paid > 0 && row.total_paid >= threshold, [row, threshold]);
  const isPaid = useMemo(() => row.status === 'paid' || row.status === 'autodraft' || isPaidByThreshold, [row.status, isPaidByThreshold]);
  const isSkipped = useMemo(() => !!row.is_skipped, [row.is_skipped]);
  
  const effectiveStatus = useMemo(() => {
    if (isSkipped) return 'skipped';
    if (isPaidByThreshold && row.status !== 'paid' && row.status !== 'autodraft') return 'paid';
    return row.status;
  }, [isSkipped, isPaidByThreshold, row.status]);
  
  const rowBg = useMemo(() => isSkipped ? '' : (ROW_STATUS_CLS[effectiveStatus] || ''), [isSkipped, effectiveStatus]);
  const remaining = useMemo(() => Math.max((threshold || 0) - (row.total_paid || 0), 0), [threshold, row.total_paid]);

  async function handleQuickPay() {
    const val = parseFloat(amountRef.current?.value);
    if (!val || val <= 0) { toast.error('Enter a payment amount'); return; }
    try {
      await api.quickPay({ bill_id: row.id, amount: val, paid_date: defaultPaymentDate });
      toast.success('Marked as paid');
      refresh();
    } catch (err) {
      toast.error(err.message);
    }
  }

  return (
    <>
      <div
        className={cn(
          'rounded-lg border border-border/60 bg-background/60 p-3 shadow-sm',
          'space-y-3 transition-colors',
          isSkipped ? 'opacity-55' : rowBg,
        )}
        style={{ animationDelay: `${index * 40}ms` }}
      >
        <div className="flex min-w-0 items-start justify-between gap-3">
          <div className="min-w-0">
            <div className="flex min-w-0 items-center gap-2">
              {row.autopay_enabled && (
                <span
                  className="inline-flex shrink-0 rounded bg-sky-500/15 px-1.5 py-0.5 text-[10px] font-semibold text-sky-500"
                  title="Autopay"
                >
                  AP
                </span>
              )}
              <button
                type="button"
                onClick={() => onEditBill?.(row)}
                className={cn(
                  'min-w-0 truncate text-left text-sm font-semibold leading-tight text-foreground',
                  'underline-offset-2 transition-colors hover:text-primary hover:underline',
                  isSkipped && 'line-through',
                )}
                title="Edit bill"
              >
                {row.name}
              </button>
            </div>
            {row.monthly_notes && (
              <p className="mt-1 line-clamp-2 text-xs italic text-amber-500/80" title={row.monthly_notes}>
                {row.monthly_notes}
              </p>
            )}
          </div>
          <StatusBadge status={effectiveStatus} />
        </div>

        <div className="grid grid-cols-2 gap-x-3 gap-y-2 text-xs text-muted-foreground sm:grid-cols-4">
          <div>
            <p className="uppercase tracking-wide text-muted-foreground/60">Due</p>
            <p className="mt-0.5 font-mono text-sm text-foreground">{fmtDate(row.due_date)}</p>
          </div>
          <div>
            <p className="uppercase tracking-wide text-muted-foreground/60">Category</p>
            <p className="mt-0.5 truncate text-sm text-foreground">{row.category_name || 'Uncategorized'}</p>
          </div>
          <div>
            <p className="uppercase tracking-wide text-muted-foreground/60">Expected</p>
            <p className={cn('mt-0.5 font-mono text-sm', row.actual_amount != null ? 'text-amber-500' : 'text-foreground')}>
              {fmt(threshold)}
            </p>
          </div>
          <div>
            <p className="uppercase tracking-wide text-muted-foreground/60">Remaining</p>
            <p className={cn('mt-0.5 font-mono text-sm', remaining > 0 ? 'text-foreground' : 'text-emerald-500')}>
              {fmt(remaining)}
            </p>
          </div>
        </div>

        <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
          <div className="grid grid-cols-2 gap-2 text-xs sm:flex sm:items-center">
            <div className="rounded-md bg-muted/45 px-2 py-1.5">
              <span className="text-muted-foreground">Paid </span>
              <span className="font-mono text-emerald-500">{row.total_paid > 0 ? fmt(row.total_paid) : '—'}</span>
            </div>
            <div className="rounded-md bg-muted/45 px-2 py-1.5">
              <span className="text-muted-foreground">Date </span>
              <span className="font-mono text-foreground">{row.last_paid_date ? fmtDate(row.last_paid_date) : '—'}</span>
            </div>
          </div>

          <div className="flex flex-wrap items-center justify-end gap-1.5">
            {!isPaid && !isSkipped && (
              <div className="flex items-center gap-1.5">
                <Input
                  ref={amountRef}
                  type="number" min="0" step="0.01"
                  defaultValue={threshold}
                  className="h-8 w-24 text-right font-mono text-sm bg-background/70 border-border/60"
                  title="Payment amount"
                  aria-label={`${row.name} payment amount`}
                />
                <Button
                  size="sm" variant="default"
                  onClick={handleQuickPay}
                  className="h-8 px-3 text-xs font-semibold"
                >
                  Pay
                </Button>
              </div>
            )}

            {row.payments && row.payments.length > 0 && (
              <Button
                size="sm" variant="ghost"
                className="h-8 px-2.5 text-xs text-muted-foreground hover:text-foreground"
                title="Edit payment"
                onClick={() => setEditPayment(row.payments[0])}
              >
                <Pencil className="mr-1.5 h-3.5 w-3.5" />
                Payment
              </Button>
            )}

            <Button
              size="sm" variant="ghost"
              className="h-8 px-2.5 text-xs text-muted-foreground hover:text-foreground"
              title={`Edit ${MONTHS[month - 1]} state (actual amount, notes, skip)`}
              onClick={() => setShowMbs(true)}
            >
              <Settings2 className="mr-1.5 h-3.5 w-3.5" />
              Month
            </Button>
          </div>
        </div>
      </div>
    </>
  );
});

MobileTrackerRow.displayName = 'MobileTrackerRow';
