import { useState, useEffect, useRef, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import Layout from '../../components/Layout';
import LoadingButton from '../../components/LoadingButton';
import { supabase } from '../../lib/supabase';
import { useAuth } from '../../context/AuthContext';
import { sendEmail } from '../../lib/email';

const INVOICE_TODAY = new Date().toISOString().split('T')[0];

function newItem(description = '', unit_price = '', quantity = 1, taskId = null, isRevision = false) {
  return { id: crypto.randomUUID(), description, unit_price, quantity, task_id: taskId, is_revision: isRevision };
}

function genNumber(count) {
  const year = new Date().getFullYear();
  return `INVSUB-${year}-${String(count + 1).padStart(3, '0')}`;
}

export default function MyInvoiceCreate() {
  const navigate = useNavigate();
  const { currentUser } = useAuth();

  const [invoiceNumber, setInvoiceNumber] = useState('');
  const [completedTasks, setCompletedTasks] = useState([]);
  const [loadingTasks, setLoadingTasks] = useState(true);
  const [items, setItems] = useState([newItem()]);
  const [notes, setNotes] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');
  const dragItem = useRef(null);

  const rate = Number(currentUser?.brand_book_rate || 60);

  useEffect(() => {
    async function load() {
      const [{ data: tasks }, { data: existingInvoices }, { data: nextNum }] = await Promise.all([
        supabase
          .from('tasks')
          .select('id, title, current_version, project:projects(name)')
          .eq('status', 'client_approved')
          .eq('assigned_to', currentUser.id)
          .order('title'),
        supabase
          .from('subcontractor_invoices')
          .select('id, status, items:subcontractor_invoice_items(task_id)')
          .in('status', ['submitted', 'paid']),
        supabase.rpc('get_next_sub_invoice_number'),
      ]);

      setInvoiceNumber(nextNum || genNumber(0));

      const invoicedTaskIds = new Set(
        (existingInvoices || []).flatMap(inv => (inv.items || []).map(i => i.task_id).filter(Boolean))
      );
      setCompletedTasks((tasks || []).filter(t => !invoicedTaskIds.has(t.id)));
      setLoadingTasks(false);
    }
    load();
  }, []);

  const addedTaskIds = useMemo(() => new Set(items.map(i => i.task_id).filter(Boolean)), [items]);

  const addTask = (task) => {
    if (addedTaskIds.has(task.id)) return;
    const version = task.current_version || 0;
    const baseDesc = task.project?.name ? `${task.project.name} • ${task.title}` : task.title;
    const toAdd = [newItem(`${baseDesc} – R00`, rate, 1, task.id, false)];
    for (let v = 1; v <= version; v++) {
      toAdd.push(newItem(`${baseDesc} – R${String(v).padStart(2, '0')}`, 30, 1, task.id, true));
    }
    setItems(prev => {
      if (prev.length === 1 && !prev[0].description && !prev[0].unit_price) return toAdd;
      return [...prev, ...toAdd];
    });
  };

  const updateItem = (id, field, value) => {
    setItems(prev => prev.map(item => item.id === id ? { ...item, [field]: value } : item));
  };

  const removeItem = (id) => setItems(prev => prev.filter(item => item.id !== id));

  const handleDrop = (targetIndex) => {
    if (dragItem.current === null || dragItem.current === targetIndex) { dragItem.current = null; return; }
    setItems(prev => {
      const next = [...prev];
      const [moved] = next.splice(dragItem.current, 1);
      next.splice(targetIndex, 0, moved);
      return next;
    });
    dragItem.current = null;
  };

  const total = items.reduce((s, i) => s + (Number(i.quantity) || 0) * (Number(i.unit_price) || 0), 0);

  const handleSubmit = async () => {
    const valid = items.filter(i => String(i.description).trim());
    if (!valid.length) { setError('Add at least one line item.'); return; }
    setSaving(true);
    setError('');
    try {
      const { data: inv, error: invErr } = await supabase
        .from('subcontractor_invoices')
        .insert({
          profile_id: currentUser.id,
          invoice_number: invoiceNumber.trim(),
          status: 'submitted',
          notes: notes.trim(),
          submitted_at: new Date().toISOString(),
        })
        .select()
        .single();
      if (invErr) throw invErr;

      const { error: itemsErr } = await supabase.from('subcontractor_invoice_items').insert(
        valid.map((item, idx) => ({
          invoice_id: inv.id,
          task_id: item.task_id || null,
          description: String(item.description).trim(),
          quantity: Number(item.quantity) || 1,
          unit_price: Number(item.unit_price) || 0,
          sort_order: idx,
        }))
      );
      if (itemsErr) throw itemsErr;

      const total = valid.reduce((s, i) => s + (Number(i.unit_price) || 0) * (Number(i.quantity) || 1), 0);
      sendEmail('subcontractor_invoice_submitted', 'hello@fourgebranding.com', {
        subName: currentUser.name,
        invoiceNumber: inv.invoice_number,
        total: total.toFixed(2),
        invoiceId: inv.id,
      }).catch(err => console.error('Sub invoice notification failed:', err));

      navigate(`/my-invoices-sub/${inv.id}`);
    } catch (err) {
      setError(err.message);
      setSaving(false);
    }
  };

  return (
    <Layout>
      <button className="back-link" onClick={() => navigate('/my-invoices-sub')}>← Back to Invoices</button>

      <div className="page-header">
        <div>
          <div className="page-title">New Invoice</div>
          <div className="page-subtitle">
            Invoice date: {new Date(INVOICE_TODAY).toLocaleDateString()} · {invoiceNumber}
          </div>
        </div>
      </div>

      {error && <div className="notification notification-info" style={{ marginBottom: 16 }}>{error}</div>}

      <div className="card" style={{ marginBottom: 24 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <div className="card-title" style={{ marginBottom: 0 }}>Completed Tasks</div>
          {completedTasks.length > 0 && !loadingTasks && (
            <button
              className="btn btn-outline btn-sm"
              onClick={() => completedTasks.forEach(task => { if (!addedTaskIds.has(task.id)) addTask(task); })}
            >
              + Add All
            </button>
          )}
        </div>
        {loadingTasks ? (
          <p style={{ fontSize: 13, color: 'var(--text-muted)' }}>Loading...</p>
        ) : completedTasks.length === 0 ? (
          <p style={{ fontSize: 13, color: 'var(--text-muted)' }}>No completed tasks available to invoice.</p>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {completedTasks.map(task => {
              const alreadyAdded = addedTaskIds.has(task.id);
              return (
                <div key={task.id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 12px', background: 'var(--bg)', borderRadius: 4, border: '1px solid var(--border)' }}>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 400 }}>
                      {task.project?.name ? `${task.project.name} • ` : ''}{task.title}
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                      {(() => {
                        const v = task.current_version || 0;
                        const parts = [`R00 New Book $${rate.toFixed(2)}`];
                        if (v > 0) parts.push(`+ ${v} Revision${v > 1 ? 's' : ''} @ $30ea`);
                        return parts.join(' · ');
                      })()}
                    </div>
                  </div>
                  <button
                    className={`btn btn-sm ${alreadyAdded ? 'btn-outline' : 'btn-primary'}`}
                    onClick={() => !alreadyAdded && addTask(task)}
                    disabled={alreadyAdded}
                  >
                    {alreadyAdded ? 'Added' : '+ Add'}
                  </button>
                </div>
              );
            })}
          </div>
        )}
      </div>

      <div className="card" style={{ marginBottom: 24 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <div className="card-title" style={{ marginBottom: 0 }}>Line Items</div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '20px 90px 1fr 80px 120px 120px 40px', gap: 8, marginBottom: 8 }}>
          {['', 'Type', 'Description', 'Qty / Hrs', 'Rate', 'Total', ''].map((h, i) => (
            <div key={i} style={{ fontSize: 11, fontWeight: 400, textTransform: 'uppercase', letterSpacing: '0.5px', color: 'var(--text-muted)', textAlign: i > 3 ? 'right' : 'left' }}>{h}</div>
          ))}
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {items.map((item, index) => (
            <div
              key={item.id}
              onDragOver={e => e.preventDefault()}
              onDrop={() => handleDrop(index)}
              style={{ display: 'grid', gridTemplateColumns: '20px 90px 1fr 80px 120px 120px 40px', gap: 8, alignItems: 'center' }}
            >
              <div
                draggable
                onDragStart={e => { dragItem.current = index; e.dataTransfer.effectAllowed = 'move'; }}
                style={{ cursor: 'grab', color: 'var(--text-muted)', fontSize: 14, textAlign: 'center', userSelect: 'none' }}
              >⠿</div>
              <span className={`badge ${item.is_revision ? 'badge-client_revision' : 'badge-initial'}`}>
                {item.is_revision ? 'Revision' : 'New'}
              </span>
              <input
                type="text"
                placeholder="Description..."
                value={item.description}
                onChange={e => updateItem(item.id, 'description', e.target.value)}
                style={{ margin: 0 }}
              />
              <input
                type="number"
                min="0.5"
                step="0.5"
                value={item.quantity}
                onChange={e => updateItem(item.id, 'quantity', e.target.value)}
                style={{ margin: 0, textAlign: 'center' }}
              />
              <input
                type="number"
                min="0"
                step="0.01"
                placeholder="0.00"
                value={item.unit_price}
                onChange={e => updateItem(item.id, 'unit_price', e.target.value)}
                style={{ margin: 0, textAlign: 'right' }}
              />
              <div style={{ textAlign: 'right', fontSize: 14, fontWeight: 400, color: 'var(--text-primary)', paddingRight: 4 }}>
                ${((Number(item.quantity) || 0) * (Number(item.unit_price) || 0)).toFixed(2)}
              </div>
              <button onClick={() => removeItem(item.id)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger)', fontSize: 16, padding: 4 }}>✕</button>
            </div>
          ))}
        </div>

        <button className="btn btn-outline btn-sm" style={{ marginTop: 12 }} onClick={() => setItems(prev => [...prev, newItem()])}>
          + Add Line Item
        </button>

        <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
          <div style={{ textAlign: 'right' }}>
            <div style={{ fontSize: 11, fontWeight: 400, textTransform: 'uppercase', letterSpacing: '0.5px', color: 'var(--text-muted)', marginBottom: 4 }}>Total</div>
            <div style={{ fontSize: 26, fontWeight: 400, color: 'var(--accent)' }}>${total.toFixed(2)}</div>
          </div>
        </div>
      </div>

      <div className="card" style={{ marginBottom: 24 }}>
        <div className="card-title">Notes</div>
        <textarea
          placeholder="Additional notes for the team..."
          value={notes}
          onChange={e => setNotes(e.target.value)}
          style={{ minHeight: 80 }}
        />
      </div>

      <div className="action-buttons">
        <LoadingButton className="btn btn-primary" onClick={handleSubmit} loading={saving} loadingText="Submitting...">
          Submit Invoice
        </LoadingButton>
        <button className="btn btn-outline" onClick={() => navigate('/my-invoices-sub')} disabled={saving}>Cancel</button>
      </div>
    </Layout>
  );
}
