import { Check, Copy, GitBranch, MoreHorizontal, Plus, Search, Sparkles, Workflow } from 'lucide-react';
import { useEffect, useMemo, useState, type FormEvent } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useApp } from '../context/AppContext';
import { ApiError } from '../services/api';
import { flowsApi } from '../services/domain';
import type { Flow } from '../types';

const statusLabels: Record<string, string> = { draft: 'Draft', published: 'Published', paused: 'Paused', archived: 'Archived' };

export function FlowsPage() {
    const { current, can } = useApp();
    const navigate = useNavigate();
    const [flows, setFlows] = useState<Flow[]>([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState('');
    const [query, setQuery] = useState('');
    const [filter, setFilter] = useState('all');
    const [showCreate, setShowCreate] = useState(false);
    const [editing, setEditing] = useState<Flow | null>(null);
    const [editName, setEditName] = useState('');
    const [editDescription, setEditDescription] = useState('');
    const [name, setName] = useState('');
    const [description, setDescription] = useState('');
    const [busy, setBusy] = useState(false);
    const [notice, setNotice] = useState('');

    async function refresh() {
        if (!current) return;
        setLoading(true);
        try {
            setFlows((await flowsApi.list(current.workspace.id)).items);
            setError('');
        } catch (cause) {
            setError(cause instanceof Error ? cause.message : 'Could not load flows.');
        } finally {
            setLoading(false);
        }
    }
    useEffect(() => { void refresh(); }, [current?.workspace.id]);
    const filtered = useMemo(() => flows.filter((flow) =>
        (filter === 'all' || flow.status === filter) && flow.name.toLowerCase().includes(query.toLowerCase()),
    ), [flows, filter, query]);

    async function create(event: FormEvent) {
        event.preventDefault();
        if (!current || busy) return;
        setBusy(true);
        try {
            const flow = await flowsApi.create(current.workspace.id, { name, description });
            setShowCreate(false);
            navigate(`/app/automation/flows/${flow.id}`);
        } catch (cause) {
            setError(cause instanceof Error ? cause.message : 'Unable to create flow.');
        } finally { setBusy(false); }
    }

    async function duplicate(flow: Flow) {
        if (!current) return;
        try {
            const copy = await flowsApi.duplicate(current.workspace.id, flow.id);
            navigate(`/app/automation/flows/${copy.id}`);
        } catch (cause) { setError(cause instanceof Error ? cause.message : 'Could not duplicate flow.'); }
    }
    async function update(event: FormEvent) {
        event.preventDefault();
        if (!current || !editing || busy) return;
        setBusy(true);
        try {
            await flowsApi.update(current.workspace.id, editing.id, { name: editName, description: editDescription });
            setEditing(null);
            setNotice('Flow details updated.');
            await refresh();
        } catch (cause) { setError(cause instanceof Error ? cause.message : 'Could not update flow details.'); }
        finally { setBusy(false); }
    }
    async function publish(flow: Flow) {
        if (!current) return;
        try {
            await flowsApi.publish(current.workspace.id, flow.id);
            setNotice(`${flow.name} published.`);
            await refresh();
        } catch (cause) {
            setError(cause instanceof ApiError ? Object.values(cause.fields).flat().join(' ') || cause.message : 'Could not publish flow.');
        }
    }
    async function pause(flow: Flow) {
        if (!current) return;
        try { await flowsApi.pause(current.workspace.id, flow.id); await refresh(); }
        catch (cause) { setError(cause instanceof Error ? cause.message : 'Could not pause flow.'); }
    }
    async function remove(flow: Flow) {
        if (!current || !window.confirm(`Delete “${flow.name}”? This cannot be undone.`)) return;
        try { await flowsApi.remove(current.workspace.id, flow.id); await refresh(); }
        catch (cause) { setError(cause instanceof Error ? cause.message : 'Could not delete flow.'); }
    }

    return (
        <div className="flows-page">
            <div className="page-heading">
                <div><div className="eyebrow">AUTOMATION</div><h1>Flows</h1><p>Design automated conversations that work while you sleep.</p></div>
                {can('flows.create') && <button className="button button-primary" onClick={() => setShowCreate(true)}><Plus size={17} /> New flow</button>}
            </div>
            {notice && <div className="alert-success">{notice}<button onClick={() => setNotice('')}>×</button></div>}
            {error && <div role="alert" className="alert-error">{error}<button onClick={() => setError('')}>×</button></div>}
            <div className="panel flows-panel">
                <div className="flow-toolbar">
                    <label className="table-search"><Search size={16} /><input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search flows..." /></label>
                    <div className="filter-tabs">
                        {['all', 'draft', 'published', 'paused'].map((value) => <button className={filter === value ? 'selected' : ''} key={value} onClick={() => setFilter(value)}>{value === 'all' ? 'All flows' : statusLabels[value]}</button>)}
                    </div>
                </div>
                <div className="table-wrap">
                    <table className="data-table flows-table">
                        <thead><tr><th>Flow name</th><th>Status</th><th>Version</th><th>Updated</th><th>Published</th><th>Executions</th><th /></tr></thead>
                        <tbody>
                            {loading && <tr><td colSpan={7}><div className="table-loading">Loading flows…</div></td></tr>}
                            {!loading && filtered.map((flow) => (
                                <tr key={flow.id}>
                                    <td><Link to={`/app/automation/flows/${flow.id}`} className="flow-name-cell"><span className="flow-list-icon"><Workflow size={17} /></span><span><b>{flow.name}</b><small>{flow.description || 'No description'}</small></span></Link></td>
                                    <td><span className={`status-pill ${flow.status}`}><i />{statusLabels[flow.status] ?? flow.status}</span></td>
                                    <td><span className="version-label">v{flow.version || 0}</span></td>
                                    <td>{new Date(flow.updated_at).toLocaleDateString()}</td>
                                    <td>{flow.published_at ? new Date(flow.published_at).toLocaleDateString() : '—'}</td>
                                    <td>{(flow.executions_count ?? 0).toLocaleString()}</td>
                                    <td><div className="row-actions">
                                        <Link className="table-action" to={`/app/automation/flows/${flow.id}`}>Open</Link>
                                        <button className="icon-button small" aria-label={`Actions for ${flow.name}`} onClick={(event) => {
                                            const menu = event.currentTarget.nextElementSibling;
                                            menu?.classList.toggle('visible');
                                        }}><MoreHorizontal size={18} /></button>
                                        <div className="row-menu">
                                            {can('flows.create') && <button onClick={() => void duplicate(flow)}><Copy size={14} />Duplicate</button>}
                                            {can('flows.update') && <button onClick={() => { setEditing(flow); setEditName(flow.name); setEditDescription(flow.description ?? ''); }}><GitBranch size={14} />Edit details</button>}
                                            {flow.status === 'draft' && can('flows.publish') && <button onClick={() => void publish(flow)}><Sparkles size={14} />Publish</button>}
                                            {flow.status === 'published' && can('flows.update') && <button onClick={() => void pause(flow)}><GitBranch size={14} />Pause</button>}
                                            {can('flows.delete') && <button className="danger-text" onClick={() => void remove(flow)}>Delete</button>}
                                        </div>
                                    </div></td>
                                </tr>
                            ))}
                            {!loading && filtered.length === 0 && <tr><td colSpan={7}><div className="empty-state"><span className="empty-icon"><Workflow size={23} /></span><b>{flows.length ? 'No flows match your search' : 'Create your first automation'}</b><p>{flows.length ? 'Try a different name or status filter.' : 'Start building a helpful conversation for your customers.'}</p>{!flows.length && can('flows.create') && <button className="button button-primary" onClick={() => setShowCreate(true)}><Plus size={16} />Create a flow</button>}</div></td></tr>}
                        </tbody>
                    </table>
                </div>
            </div>
            {showCreate && <div className="modal-backdrop" role="presentation" onMouseDown={(event) => { if (event.target === event.currentTarget) setShowCreate(false); }}>
                <form className="modal-card" onSubmit={(event) => void create(event)}>
                    <button type="button" className="modal-close" onClick={() => setShowCreate(false)}>×</button>
                    <div className="modal-icon"><Workflow size={20} /></div><div className="eyebrow">NEW AUTOMATION</div><h2>Create a flow</h2><p>Give your automation a clear name. You can add a description later.</p>
                    <label>Flow name<input autoFocus value={name} onChange={(event) => setName(event.target.value)} maxLength={255} required placeholder="e.g. Welcome new customers" /></label>
                    <label>Description <span className="optional-label">Optional</span><textarea value={description} onChange={(event) => setDescription(event.target.value)} rows={3} placeholder="What will this flow help customers with?" /></label>
                    <div className="modal-actions"><button className="button button-quiet" type="button" onClick={() => setShowCreate(false)}>Cancel</button><button className="button button-primary" disabled={busy}>{busy ? 'Creating…' : 'Create flow'}<Plus size={16} /></button></div>
                </form>
            </div>}
            {editing && <div className="modal-backdrop"><form className="modal-card" onSubmit={(event) => void update(event)}><button type="button" className="modal-close" onClick={() => setEditing(null)}>×</button><div className="modal-icon"><Workflow size={20} /></div><div className="eyebrow">FLOW DETAILS</div><h2>Edit flow</h2><p>Update the name or description shown to your team.</p><label>Flow name<input autoFocus value={editName} onChange={(event) => setEditName(event.target.value)} required maxLength={255} /></label><label>Description<textarea rows={3} value={editDescription} onChange={(event) => setEditDescription(event.target.value)} /></label><div className="modal-actions"><button type="button" className="button button-quiet" onClick={() => setEditing(null)}>Cancel</button><button className="button button-primary" disabled={busy}>{busy ? 'Saving…' : 'Save details'}<Check size={15} /></button></div></form></div>}
        </div>
    );
}
