import React, { useState } from 'react';
import { getErrorMessage } from '@nexuscrm/host-sdk';
import { Clock, CheckCircle, XCircle, AlertCircle, AlertTriangle, MessageSquare, RotateCcw, ShieldCheck, UserPlus } from 'lucide-react';
import { Button } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { approvalsAPI } from '../../infrastructure/api/approvals';
import type { ProcessActionFailure, ProcessResult, RecordApprovalStatus } from './approvalTypes';
import { ReassignModal } from '../record/components/ReassignModal';
import { useSuccessToast, useErrorToast } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { useRuntime, useSystemPermission } from '@nexuscrm/host-sdk';
import { COMMON_FIELDS } from '../../core/constants';
import { APPROVAL_STATUS } from './approvalConstants';
import { formatDate } from '../../core/utils/formatting';
import {
    findPendingAssignmentForUser,
    formatPendingApproverNames,
    pendingAssignmentsFor,
} from './approvalPendingAssignments';

interface ApprovalBannerProps {
    /** Approval status data (from useRecordApproval) */
    pendingItem: RecordApprovalStatus | null;
    onActionComplete: (result?: ProcessResult) => void;
}

function formatActionFailure(failure: ProcessActionFailure): string {
    const actionLabel = failure.actionName || failure.actionType || 'Configured action';
    const fieldLabel = failure.field ? ` (${failure.field})` : '';
    const reason = failure.reason || 'No reason provided';
    return `${actionLabel}${fieldLabel}: ${reason}`;
}

export function ApprovalActionFailureWarning({ failures }: { failures: ProcessActionFailure[] }) {
    if (failures.length === 0) {
        return null;
    }

    return (
        <div
            role="alert"
            className="mb-6 flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800"
        >
            <AlertTriangle className="mt-0.5 h-4 w-4 flex-shrink-0 text-amber-600" />
            <div>
                <p className="font-medium">Approval action completed, but some configured actions failed.</p>
                <ul className="mt-1 list-disc space-y-1 pl-4">
                    {failures.map((failure, index) => (
                        <li key={`${failure.actionName || failure.actionType}-${index}`}>
                            {formatActionFailure(failure)}
                        </li>
                    ))}
                </ul>
            </div>
        </div>
    );
}

/**
 * Banner component shown on record detail when approval is pending.
 * - Shows pending status with submitter info
 * - If current user is the approver, shows inline Approve/Reject buttons
 * - If current user holds ModifyAllData, shows the same actions to act on
 *   behalf of the assigned approver (the engine authorizes this override and
 *   records the acting user as ActorId in the approval history), plus Recall
 *   on behalf of the submitter
 */
export function ApprovalBanner({
    pendingItem,
    onActionComplete,
}: ApprovalBannerProps) {
    const { user } = useRuntime();
    const canModifyAllData = useSystemPermission('ModifyAllData');
    const showSuccess = useSuccessToast();
    const showError = useErrorToast();

    const [processing, setProcessing] = useState(false);
    const [showCommentInput, setShowCommentInput] = useState(false);
    const [actionType, setActionType] = useState<'approve' | 'reject' | 'recall' | null>(null);
    const [comments, setComments] = useState('');
    const [showReassignModal, setShowReassignModal] = useState(false);

    // No pending item = no banner
    if (!pendingItem || pendingItem.status !== APPROVAL_STATUS.PENDING) {
        return null;
    }

    const userId = user?.[COMMON_FIELDS.ID] as string | undefined;
    const pendingAssignments = pendingAssignmentsFor(pendingItem);
    const userAssignment = findPendingAssignmentForUser(pendingAssignments, userId);
    const isApprover = Boolean(userAssignment);
    const isSubmitter = userId === pendingItem.submittedById;
    const userWorkItemId = userAssignment?.workItemId;
    const recallWorkItemId = pendingItem.pendingWorkItemId
        || pendingAssignments.find(assignment => assignment.workItemId)?.workItemId;
    const approverNames = formatPendingApproverNames(pendingAssignments, pendingItem.approverName || 'Any approver');
    // ModifyAllData holders may act on behalf of the assigned approver; the
    // engine enforces the same override server-side. Each decision applies to
    // one pending work item: on first-response steps that completes the step,
    // on unanimous steps the remaining approvers' work items stay pending.
    const onBehalfAssignment = canModifyAllData && !userWorkItemId
        ? pendingAssignments.find(assignment => assignment.workItemId)
        : undefined;
    const onBehalfWorkItemId = canModifyAllData && !userWorkItemId
        ? (onBehalfAssignment?.workItemId || pendingItem.pendingWorkItemId)
        : undefined;
    const isActingOnBehalf = Boolean(onBehalfWorkItemId);
    const actionWorkItemId = userWorkItemId || onBehalfWorkItemId;
    const onBehalfApproverName = onBehalfAssignment?.actorName
        || onBehalfAssignment?.originalActorName
        || pendingItem.approverName
        || 'the assigned approver';
    // Recall is a submitter action; ModifyAllData holders may also recall on
    // behalf of the submitter (the engine enforces the same override).
    const canRecall = (isSubmitter || canModifyAllData) && Boolean(recallWorkItemId);

    const handleAction = async (action: 'approve' | 'reject' | 'recall') => {
        if (showCommentInput && actionType === action) {
            // Execute the action
            const targetWorkItemId = action === 'recall' ? recallWorkItemId : actionWorkItemId;
            if (!targetWorkItemId) {
                showError('No pending approval work item is available for this action');
                return;
            }
            setProcessing(true);
            try {
                let result: ProcessResult | undefined;
                if (action === 'approve') {
                    result = await approvalsAPI.approve(targetWorkItemId, comments);
                    showSuccess('Approval granted successfully');
                } else if (action === 'reject') {
                    result = await approvalsAPI.reject(targetWorkItemId, comments);
                    showSuccess('Approval rejected');
                } else if (action === 'recall') {
                    result = await approvalsAPI.recall(targetWorkItemId, comments);
                    showSuccess('Approval request recalled');
                }
                setShowCommentInput(false);
                setComments('');
                onActionComplete(result);
            } catch (err: unknown) {
                showError(`Failed to ${action}: ${getErrorMessage(err)}`);
            } finally {
                setProcessing(false);
            }
        } else {
            // Show comment input
            setActionType(action);
            setShowCommentInput(true);
            setComments('');
        }
    };

    const handleCancel = () => {
        setShowCommentInput(false);
        setActionType(null);
        setComments('');
    };

    return (
        <div className={`rounded-lg border p-4 mb-6 ${isApprover
            ? 'bg-amber-50 border-amber-200'
            : 'bg-blue-50 border-blue-200'
            }`}>
            <div className="flex items-start justify-between gap-4">
                <div className="flex items-start gap-3">
                    <div className={`p-2 rounded-full ${isApprover ? 'bg-amber-100' : 'bg-blue-100'
                        }`}>
                        {isApprover ? (
                            <AlertCircle className="w-5 h-5 text-amber-600" />
                        ) : (
                            <Clock className="w-5 h-5 text-blue-600" />
                        )}
                    </div>
                    <div>
                        <h3 className={`font-semibold ${isApprover ? 'text-amber-900' : 'text-blue-900'
                            }`}>
                            {isApprover
                                ? '🔔 Approval Request for You'
                                : '⏳ Pending Approval'}
                        </h3>
                        <div className="text-xs text-blue-700">
                            {isSubmitter
                                ? 'You submitted this request'
                                : `Submitted by ${pendingItem.submitterName || 'someone'}`
                            }
                            {pendingItem.createdDate && (
                                <span> on {formatDate(pendingItem.createdDate)}</span>
                            )}
                        </div>
                        {pendingItem.comments && (
                            <div className="text-xs text-blue-600 mt-1 italic opacity-80 flex items-start gap-1">
                                <MessageSquare size={12} className="mt-0.5 shrink-0" />
                                <span className="whitespace-pre-wrap break-words min-w-0">"{pendingItem.comments}"</span>
                            </div>
                        )}
                        {!isApprover && (
                            <p className="text-sm text-gray-500 mt-2">
                                Waiting for: <span className="font-medium">{approverNames}</span>
                            </p>
                        )}
                        {isActingOnBehalf && (
                            <p className="text-xs text-indigo-700 mt-1 flex items-start gap-1">
                                <ShieldCheck size={12} className="mt-0.5 shrink-0" />
                                <span>
                                    You can act on this request as an administrator, on behalf
                                    of <span className="font-medium">{onBehalfApproverName}</span>.
                                    Your decision is recorded under your name in the approval history.
                                </span>
                            </p>
                        )}
                    </div>
                </div>

                {/* Action buttons for the assigned approver, or a ModifyAllData
                    admin acting on the approver's behalf */}
                {actionWorkItemId && !showCommentInput && (
                    <div className="flex items-center gap-2 flex-shrink-0">
                        <Button
                            variant="primary"
                            size="sm"
                            icon={<CheckCircle className="w-4 h-4" />}
                            onClick={() => handleAction('approve')}
                            disabled={processing}
                        >
                            Approve
                        </Button>
                        <Button
                            variant="danger"
                            size="sm"
                            icon={<XCircle className="w-4 h-4" />}
                            onClick={() => handleAction('reject')}
                            disabled={processing}
                        >
                            Reject
                        </Button>
                        <Button
                            variant="secondary"
                            size="sm"
                            icon={<UserPlus className="w-4 h-4" />}
                            onClick={() => setShowReassignModal(true)}
                            disabled={processing}
                        >
                            Reassign
                        </Button>
                        {/* Submitter (or a ModifyAllData admin on their behalf)
                            can also recall even when they are the approver */}
                        {canRecall && (
                            <Button
                                variant="secondary"
                                size="sm"
                                icon={<RotateCcw className="w-4 h-4" />}
                                onClick={() => handleAction('recall')}
                                disabled={processing}
                            >
                                Recall
                            </Button>
                        )}
                    </div>
                )}

                {/* Action button for a recaller with no approve/reject entitlement (Recall only) */}
                {canRecall && !actionWorkItemId && !showCommentInput && (
                    <div className="flex items-center gap-2 flex-shrink-0">
                        <Button
                            variant="secondary"
                            size="sm"
                            icon={<RotateCcw className="w-4 h-4" />}
                            onClick={() => handleAction('recall')}
                            disabled={processing}
                        >
                            Recall
                        </Button>
                    </div>
                )}
            </div>

            {/* Comment input for action */}
            {
                showCommentInput && (
                    <div className="mt-4 pt-4 border-t border-gray-200">
                        <label className="block text-sm font-medium text-gray-700 mb-2">
                            {actionType === 'approve' ? 'Approval' : actionType === 'reject' ? 'Rejection' : 'Recall'} Comments (optional)
                        </label>
                        <textarea
                            value={comments}
                            onChange={(e) => setComments(e.target.value)}
                            placeholder={`Add comments for your ${actionType}...`}
                            className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                            rows={2}
                            autoFocus
                        />
                        <div className="flex justify-end gap-2 mt-3">
                            <Button
                                variant="ghost"
                                size="sm"
                                onClick={handleCancel}
                                disabled={processing}
                            >
                                Cancel
                            </Button>
                            <Button
                                variant={actionType === 'approve' ? 'primary' : actionType === 'reject' ? 'danger' : 'secondary'}
                                size="sm"
                                onClick={() => handleAction(actionType!)}
                                disabled={processing || (actionType === 'recall' ? !recallWorkItemId : !actionWorkItemId)}
                                icon={actionType === 'approve'
                                    ? <CheckCircle className="w-4 h-4" />
                                    : actionType === 'reject' ? <XCircle className="w-4 h-4" /> : <RotateCcw className="w-4 h-4" />
                                }
                            >
                                {processing
                                    ? 'Processing...'
                                    : actionType === 'approve' ? 'Confirm Approval' : actionType === 'reject' ? 'Confirm Rejection' : 'Confirm Recall'
                                }
                            </Button>
                        </div>
                    </div>
                )
            }

            <ReassignModal
                isOpen={showReassignModal}
                onClose={() => setShowReassignModal(false)}
                workItem={actionWorkItemId ? { Id: actionWorkItemId } : null}
                onSuccess={onActionComplete}
            />
        </div>
    );
}
