import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { FolderLock, Plus, Trash2, ChevronRight, ArrowLeft, Pencil } from 'lucide-react';
import {
    getFolderShares,
    addFolderShares,
    deleteFolderShare,
    type FolderShare,
    type FolderShareAccessType,
    type FolderShareType,
} from '../infrastructure/api/folders';
import { api } from '../infrastructure/api/client';

type FolderTypeFilter = 'All' | 'Report' | 'Dashboard';
type AccessTypeFilter = 'All' | 'Hidden' | 'Public' | 'Shared';
import { ConfirmationModal } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { useErrorToast, useSuccessToast } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { formatApiError } from '@nexuscrm/host-sdk';
import { PowerList, PowerListColumn } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { Badge } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { Tooltip } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';

// ─────────────────────────────────────────────────────────────────────────────
// Types
// ─────────────────────────────────────────────────────────────────────────────

interface Folder {
    Id: string;
    Name: string;
    Label: string;
    Type: string;
    AccessType: string;
}

interface AddShareFormData {
    sharedToId: string;
    sharedToType: FolderShareType;
    accessLevel: FolderShareAccessType;
}

const EMPTY_SHARE_FORM: AddShareFormData = {
    sharedToId: '',
    sharedToType: 'User',
    accessLevel: 'View',
};

const SHARED_TO_TYPE_OPTIONS: Array<{ value: AddShareFormData['sharedToType']; label: string }> = [
    { value: 'User', label: 'User' },
    { value: 'Role', label: 'Role' },
    { value: 'Group', label: 'Public Group' },
    { value: 'RoleAndSubordinates', label: 'Role and Subordinates' },
    { value: 'Organization', label: 'Organization (All Users)' },
];

// ─────────────────────────────────────────────────────────────────────────────
// AddShareModal
// ─────────────────────────────────────────────────────────────────────────────

interface AddShareModalProps {
    isOpen: boolean;
    folderName: string;
    onClose: () => void;
    onSave: (data: AddShareFormData) => Promise<void>;
    submitting: boolean;
}

const AddShareModal: React.FC<AddShareModalProps> = ({
    isOpen,
    folderName,
    onClose,
    onSave,
    submitting,
}) => {
    const [form, setForm] = useState<AddShareFormData>(EMPTY_SHARE_FORM);
    const [errors, setErrors] = useState<Partial<Record<keyof AddShareFormData, string>>>({});

    useEffect(() => {
        if (!isOpen) return;
        setForm(EMPTY_SHARE_FORM);
        setErrors({});
    }, [isOpen]);

    if (!isOpen) return null;

    const validate = (): boolean => {
        const next: typeof errors = {};
        if (form.sharedToType !== 'Organization' && !form.sharedToId.trim()) {
            next.sharedToId = 'ID is required';
        }
        setErrors(next);
        return Object.keys(next).length === 0;
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!validate()) return;
        await onSave(form);
    };

    const isOrgType = form.sharedToType === 'Organization';

    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
            <div className="bg-white rounded-xl shadow-2xl w-full max-w-md mx-4 overflow-hidden">
                <div className="px-6 py-4 border-b border-slate-200">
                    <h2 className="text-lg font-semibold text-slate-800">Add Share</h2>
                    <p className="text-sm text-slate-500 mt-0.5">Folder: {folderName}</p>
                </div>

                <form id="add-share-form" onSubmit={handleSubmit} className="px-6 py-4 space-y-4">
                    {/* SharedToType */}
                    <div>
                        <label className="block text-sm font-medium text-slate-700 mb-1">
                            Share With <span className="text-red-500">*</span>
                        </label>
                        <select
                            value={form.sharedToType}
                            onChange={e => setForm(f => ({ ...f, sharedToType: e.target.value as AddShareFormData['sharedToType'], sharedToId: '' }))}
                            className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                        >
                            {SHARED_TO_TYPE_OPTIONS.map(opt => (
                                <option key={opt.value} value={opt.value}>{opt.label}</option>
                            ))}
                        </select>
                    </div>

                    {/* SharedToId — hidden for Organization */}
                    {!isOrgType && (
                        <div>
                            <label className="block text-sm font-medium text-slate-700 mb-1">
                                {form.sharedToType === 'User' ? 'User ID' : form.sharedToType === 'Role' || form.sharedToType === 'RoleAndSubordinates' ? 'Role ID' : 'Group ID'}
                                <span className="text-red-500"> *</span>
                            </label>
                            <input
                                type="text"
                                value={form.sharedToId}
                                onChange={e => setForm(f => ({ ...f, sharedToId: e.target.value }))}
                                className={`w-full px-3 py-2 border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${errors.sharedToId ? 'border-red-400' : 'border-slate-300'}`}
                                placeholder="Enter the record ID"
                            />
                            {errors.sharedToId && <p className="mt-1 text-xs text-red-500">{errors.sharedToId}</p>}
                        </div>
                    )}

                    {/* AccessLevel */}
                    <div>
                        <label className="block text-sm font-medium text-slate-700 mb-1">
                            Access Level <span className="text-red-500">*</span>
                        </label>
                        <select
                            value={form.accessLevel}
                            onChange={e => setForm(f => ({ ...f, accessLevel: e.target.value as AddShareFormData['accessLevel'] }))}
                            className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                        >
                            <option value="View">View</option>
                            <option value="Manage">Manage</option>
                        </select>
                    </div>
                </form>

                <div className="px-6 py-4 border-t border-slate-200 flex items-center justify-end gap-3">
                    <button
                        type="button"
                        onClick={onClose}
                        disabled={submitting}
                        className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50 disabled:opacity-50"
                    >
                        Cancel
                    </button>
                    <button
                        type="submit"
                        form="add-share-form"
                        disabled={submitting}
                        className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50 flex items-center gap-2"
                    >
                        {submitting && <span className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />}
                        Add Share
                    </button>
                </div>
            </div>
        </div>
    );
};

// ─────────────────────────────────────────────────────────────────────────────
// SharesPanel — detail view for a selected folder
// ─────────────────────────────────────────────────────────────────────────────

interface SharesPanelProps {
    folder: Folder;
    onBack: () => void;
}

const SharesPanel: React.FC<SharesPanelProps> = ({ folder, onBack }) => {
    const errorToast = useErrorToast();
    const successToast = useSuccessToast();

    const [shares, setShares] = useState<FolderShare[]>([]);
    const [loading, setLoading] = useState(true);
    const [showAddModal, setShowAddModal] = useState(false);
    const [deletingShare, setDeletingShare] = useState<FolderShare | null>(null);
    const [submitting, setSubmitting] = useState(false);

    const loadShares = useCallback(async () => {
        setLoading(true);
        try {
            const data = await getFolderShares(folder.Id);
            setShares(data);
        } catch (err: unknown) {
            errorToast(`Failed to load shares: ${formatApiError(err).message}`);
        } finally {
            setLoading(false);
        }
    }, [folder.Id, errorToast]);

    useEffect(() => {
        loadShares();
    }, [loadShares]);

    const handleAddShare = async (data: AddShareFormData) => {
        setSubmitting(true);
        try {
            const sharePayload = [{
                sharedWithId: data.sharedToType === 'Organization' ? 'ALL_INTERNAL' : data.sharedToId,
                shareType: data.sharedToType,
                accessType: data.accessLevel,
            }];
            await addFolderShares(folder.Id, sharePayload);
            successToast('Share added');
            setShowAddModal(false);
            await loadShares();
        } catch (err: unknown) {
            errorToast(`Failed to add share: ${formatApiError(err).message}`);
        } finally {
            setSubmitting(false);
        }
    };

    const handleConfirmDelete = async () => {
        if (!deletingShare) return;
        try {
            await deleteFolderShare(folder.Id, deletingShare.shareId);
            successToast('Share removed');
            setDeletingShare(null);
            await loadShares();
        } catch (err: unknown) {
            errorToast(`Failed to remove share: ${formatApiError(err).message}`);
        }
    };

    const shareColumns: PowerListColumn<FolderShare>[] = [
        {
            key: 'shareType',
            label: 'Type',
            minWidth: '130px',
            render: (val) => (
                <Badge variant="info">{val ? String(val) : '—'}</Badge>
            ),
        },
        {
            key: 'sharedWithId',
            label: 'Shared To',
            minWidth: '200px',
            render: (val, row) => {
                const id = val ? String(val) : '';
                const label = row.sharedWithLabel || id;
                return (
                    <div>
                        <span className="text-sm text-slate-700">{label}</span>
                        {id && label !== id && <span className="block font-mono text-xs text-slate-400">{id}</span>}
                    </div>
                );
            },
        },
        {
            key: 'accessType',
            label: 'Access Level',
            minWidth: '110px',
            render: (val) => (
                <Badge variant={val === 'Manage' ? 'warning' : 'success'}>
                    {val ? String(val) : '—'}
                </Badge>
            ),
        },
    ];

    const renderShareActions = (share: FolderShare) => (
        <div className="flex items-center justify-end gap-1">
            <Tooltip content="Remove share" position="top">
                <button
                    onClick={() => setDeletingShare(share)}
                    className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
                >
                    <Trash2 size={16} />
                </button>
            </Tooltip>
        </div>
    );

    return (
        <div>
            <div className="flex items-center justify-between mb-6">
                <div className="flex items-center gap-3">
                    <button
                        onClick={onBack}
                        className="flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700 transition-colors"
                    >
                        <ArrowLeft size={16} />
                        All Folders
                    </button>
                    <ChevronRight size={14} className="text-slate-400" />
                    <div className="flex items-center gap-2">
                        <span className="font-semibold text-slate-800">{folder.Label || folder.Name}</span>
                        <Badge variant="neutral">{folder.Type}</Badge>
                        <Badge variant={folder.AccessType === 'Manage' ? 'warning' : 'info'}>{folder.AccessType}</Badge>
                    </div>
                </div>
                <button
                    onClick={() => setShowAddModal(true)}
                    className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium shadow-sm transition-colors text-sm"
                >
                    <Plus size={16} />
                    Add Share
                </button>
            </div>

            <PowerList<FolderShare>
                data={shares}
                columns={shareColumns}
                loading={loading}
                rowKey={(s) => s.shareId}
                searchable
                searchPlaceholder="Search shares..."
                emptyIcon={<FolderLock className="w-12 h-12" />}
                emptyTitle="No Shares"
                emptyMessage="This folder has no shares yet. Add one to grant access."
                emptyAction={{ label: 'Add Share', onClick: () => setShowAddModal(true) }}
                actions={renderShareActions}
                ariaLabel="Folder shares list"
            />

            <AddShareModal
                isOpen={showAddModal}
                folderName={folder.Label || folder.Name}
                onClose={() => setShowAddModal(false)}
                onSave={handleAddShare}
                submitting={submitting}
            />

            <ConfirmationModal
                isOpen={!!deletingShare}
                onClose={() => setDeletingShare(null)}
                onConfirm={handleConfirmDelete}
                title="Remove Share"
                message={`Remove access for "${deletingShare?.sharedWithLabel || deletingShare?.sharedWithId}" (${deletingShare?.shareType})?`}
                confirmLabel="Remove"
                variant="danger"
            />
        </div>
    );
};

// ─────────────────────────────────────────────────────────────────────────────
// FolderShareManager (main page component)
// ─────────────────────────────────────────────────────────────────────────────

export const FolderShareManager: React.FC = () => {
    const errorToast = useErrorToast();
    const successToast = useSuccessToast();

    const [folders, setFolders] = useState<Folder[]>([]);
    const [loading, setLoading] = useState(true);
    const [selectedFolder, setSelectedFolder] = useState<Folder | null>(null);
    const [typeFilter, setTypeFilter] = useState<FolderTypeFilter>('All');
    const [accessFilter, setAccessFilter] = useState<AccessTypeFilter>('All');
    const [editingAccessType, setEditingAccessType] = useState<Folder | null>(null);
    const [newAccessType, setNewAccessType] = useState<string>('');
    const [savingAccessType, setSavingAccessType] = useState(false);

    const loadFolders = useCallback(async () => {
        setLoading(true);
        try {
            // Use /folders REST API which returns human-readable labels
            const resp = await api.get<{ folders: Array<{ id: string; name: string; label: string; type: string; accessType: string }> }>(
                '/services/data/v63.0/folders?pageSize=2000'
            );
            const all = (resp.folders || []).map(f => ({
                Id: f.id,
                Name: f.name,
                Label: f.label || f.name,
                Type: f.type,
                AccessType: f.accessType,
            }));
            all.sort((a, b) => a.Label.localeCompare(b.Label));
            setFolders(all);
        } catch (err: unknown) {
            errorToast(`Failed to load folders: ${formatApiError(err).message}`);
        } finally {
            setLoading(false);
        }
    }, [errorToast]);

    useEffect(() => {
        loadFolders();
    }, [loadFolders]);

    // #2/#3: Filtered folders
    const filteredFolders = useMemo(() => {
        return folders.filter(f => {
            if (typeFilter !== 'All' && f.Type !== typeFilter) return false;
            if (accessFilter !== 'All' && f.AccessType !== accessFilter) return false;
            return true;
        });
    }, [folders, typeFilter, accessFilter]);

    // #1: AccessType edit handler
    const handleSaveAccessType = async () => {
        if (!editingAccessType || !newAccessType) return;
        setSavingAccessType(true);
        try {
            await api.patch(`/services/data/v63.0/folders/${editingAccessType.Id}`, { accessType: newAccessType });
            successToast(`Access type changed to ${newAccessType}`);
            setFolders(prev => prev.map(f =>
                f.Id === editingAccessType.Id ? { ...f, AccessType: newAccessType } : f
            ));
            setEditingAccessType(null);
        } catch (err: unknown) {
            errorToast(`Failed to update access type: ${formatApiError(err).message}`);
        } finally {
            setSavingAccessType(false);
        }
    };

    const folderColumns: PowerListColumn<Folder>[] = [
        {
            key: 'Label',
            label: 'Name',
            minWidth: '200px',
            render: (val) => (
                <span className="font-medium text-slate-900 dark:text-white">
                    {val ? String(val) : '—'}
                </span>
            ),
        },
        {
            key: 'Type',
            label: 'Type',
            minWidth: '120px',
            render: (val) => (
                <Badge variant="info">{val ? String(val) : '—'}</Badge>
            ),
        },
        {
            key: 'AccessType',
            label: 'Access Type',
            minWidth: '120px',
            render: (val) => {
                const v = val ? String(val) : '—';
                return (
                    <Badge variant={v === 'Public' ? 'success' : v === 'Shared' ? 'info' : 'neutral'}>
                        {v}
                    </Badge>
                );
            },
        },
    ];

    const renderFolderActions = (folder: Folder) => (
        <div className="flex items-center justify-end gap-1">
            <Tooltip content="Edit access type" position="top">
                <button
                    onClick={() => { setEditingAccessType(folder); setNewAccessType(folder.AccessType); }}
                    className="p-1.5 text-slate-400 hover:text-amber-600 hover:bg-amber-50 rounded-lg transition-colors"
                >
                    <Pencil size={14} />
                </button>
            </Tooltip>
            <Tooltip content="Manage shares" position="top">
                <button
                    onClick={() => setSelectedFolder(folder)}
                    className="flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium text-blue-600 hover:text-blue-700 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-colors"
                >
                    Shares <ChevronRight size={14} />
                </button>
            </Tooltip>
        </div>
    );

    if (selectedFolder) {
        return (
            <div className="max-w-7xl mx-auto p-6">
                <SharesPanel
                    folder={selectedFolder}
                    onBack={() => { setSelectedFolder(null); loadFolders(); }}
                />
            </div>
        );
    }

    return (
        <div className="max-w-7xl mx-auto p-6">
            <div className="flex items-center justify-between mb-8">
                <div className="flex items-center gap-4">
                    <div className="p-3 bg-indigo-100 rounded-lg">
                        <FolderLock className="text-indigo-600" size={32} />
                    </div>
                    <div>
                        <h1 className="text-2xl font-bold text-slate-800">Folder Sharing</h1>
                        <p className="text-slate-500">Manage who has View or Manage access to each folder.</p>
                    </div>
                </div>
            </div>

            {/* #2/#3: Filter bar */}
            <div className="flex items-center gap-3 mb-4">
                <div className="flex items-center gap-2">
                    <span className="text-sm text-slate-500">Type:</span>
                    {(['All', 'Report', 'Dashboard'] as FolderTypeFilter[]).map(t => (
                        <button
                            key={t}
                            onClick={() => setTypeFilter(t)}
                            className={`px-3 py-1 text-xs font-medium rounded-full transition-colors ${
                                typeFilter === t
                                    ? 'bg-blue-100 text-blue-700'
                                    : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
                            }`}
                        >
                            {t}
                        </button>
                    ))}
                </div>
                <div className="w-px h-5 bg-slate-200" />
                <div className="flex items-center gap-2">
                    <span className="text-sm text-slate-500">Access:</span>
                    {(['All', 'Hidden', 'Public', 'Shared'] as AccessTypeFilter[]).map(a => (
                        <button
                            key={a}
                            onClick={() => setAccessFilter(a)}
                            className={`px-3 py-1 text-xs font-medium rounded-full transition-colors ${
                                accessFilter === a
                                    ? 'bg-blue-100 text-blue-700'
                                    : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
                            }`}
                        >
                            {a}
                        </button>
                    ))}
                </div>
                {(typeFilter !== 'All' || accessFilter !== 'All') && (
                    <span className="text-xs text-slate-400 ml-2">
                        {filteredFolders.length} / {folders.length}
                    </span>
                )}
            </div>

            <PowerList<Folder>
                data={filteredFolders}
                columns={folderColumns}
                loading={loading}
                rowKey={(folder) => folder.Id}
                searchable
                searchPlaceholder="Search folders..."
                defaultSort={{ key: 'Label', direction: 'asc' }}
                emptyIcon={<FolderLock className="w-12 h-12" />}
                emptyTitle="No Folders"
                emptyMessage="No report or dashboard folders found."
                actions={renderFolderActions}
                ariaLabel="Folders list"
            />

            {/* #1: AccessType edit modal */}
            {editingAccessType && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
                    <div className="bg-white rounded-xl shadow-2xl w-full max-w-sm mx-4 overflow-hidden">
                        <div className="px-6 py-4 border-b border-slate-200">
                            <h2 className="text-lg font-semibold text-slate-800">Edit Access Type</h2>
                            <p className="text-sm text-slate-500 mt-0.5">{editingAccessType.Label || editingAccessType.Name}</p>
                        </div>
                        <div className="px-6 py-4">
                            <label className="block text-sm font-medium text-slate-700 mb-1">Access Type</label>
                            <select
                                value={newAccessType}
                                onChange={e => setNewAccessType(e.target.value)}
                                className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                            >
                                <option value="Hidden">Hidden</option>
                                <option value="Public">Public</option>
                                <option value="Shared">Shared</option>
                            </select>
                            <p className="mt-2 text-xs text-slate-400">
                                Hidden: only owner and explicit shares. Public: visible to all with folder permission. Shared: visible via shares.
                            </p>
                        </div>
                        <div className="px-6 py-4 border-t border-slate-200 flex items-center justify-end gap-3">
                            <button
                                onClick={() => setEditingAccessType(null)}
                                disabled={savingAccessType}
                                className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50 disabled:opacity-50"
                            >
                                Cancel
                            </button>
                            <button
                                onClick={handleSaveAccessType}
                                disabled={savingAccessType || newAccessType === editingAccessType.AccessType}
                                className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50 flex items-center gap-2"
                            >
                                {savingAccessType && <span className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />}
                                Save
                            </button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
};
