import React, { useMemo, useState } from 'react';
import { ChevronDown, ShieldCheck } from 'lucide-react';
import {
  useIsProposeChangesModalOpen,
  useProposeChangesRequest,
  useUISelector,
} from '../../contexts/UIContext';
import { ASSISTANT_BRAND_NAME } from '../../constants';
import { Button, ModalShell } from '../ui';
import { normalizeV1ApprovalRequestView, normalizeWriteApprovalView } from '../../utils/approvalViewModels';
import ApprovalItemList from './ApprovalItemList';

const prettyJson = (value: unknown) => {
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
};

const ProposeChangesModal = function ProposeChangesModal() {
  const open = useIsProposeChangesModalOpen();
  const req = useProposeChangesRequest();
  const resolve = useUISelector((state) => state.resolveProposeChanges);
  const [alternative, setAlternative] = useState('');
  const [showAlternativeError, setShowAlternativeError] = useState(false);

  const view = useMemo(() => {
    const record = req as Record<string, unknown> | null;
    if (record && record.protocol === 'v1') {
      return normalizeV1ApprovalRequestView(record);
    }
    return normalizeWriteApprovalView(req);
  }, [req]);

  const reset = () => {
    setAlternative('');
    setShowAlternativeError(false);
  };

  const resolveDecision = (approved: boolean, userReason?: string) => {
    resolve({
      approved,
      user_reason: approved ? undefined : (userReason?.trim() || undefined),
    });
    reset();
  };

  const submitAlternative = () => {
    const trimmed = alternative.trim();
    if (!trimmed) {
      setShowAlternativeError(true);
      return;
    }
    resolveDecision(false, trimmed);
  };

  return (
    <ModalShell
      open={open}
      title={view.modalTitle || 'Approve site action'}
      maxWidthClass="max-w-2xl"
      onClose={() => resolveDecision(false)}
      footer={(
        <div className="flex items-center justify-end gap-2">
          <Button variant="ghost" className="text-danger-text hover:bg-danger/10" onClick={() => resolveDecision(false)}>
            Reject
          </Button>
          <Button variant="success" onClick={() => resolveDecision(true)}>
            {view.approveLabel || 'Approve'}
          </Button>
        </div>
      )}
    >
      <div className="space-y-5">
        <div>
          <div className="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs font-medium uppercase tracking-wide text-app-muted-strong">
            <span className="inline-flex items-center gap-1.5">
              <ShieldCheck size={14} className="text-brand" />
              Permission required
            </span>
            <span aria-hidden="true" className="text-app-border-strong">•</span>
            <span>{view.operationCount} operation{view.operationCount === 1 ? '' : 's'}</span>
          </div>
          <h3 className="mt-2 text-lg font-semibold leading-7 text-app-text">{view.goal}</h3>
          <p className="mt-1 text-sm leading-6 text-app-muted">
            {view.approvalDescription}
          </p>
        </div>

        {view.items.length > 0 ? (
          <ApprovalItemList items={view.items} />
        ) : (
          <p className="rounded-xl border border-app-border p-4 text-sm text-app-muted">
            No operation details were provided.
          </p>
        )}

        {view.checks.length > 0 && (
          <div>
            <h4 className="mb-2 text-xs font-semibold uppercase tracking-wide text-app-muted-strong">
              Checks after approval
            </h4>
            <ApprovalItemList items={view.checks} />
          </div>
        )}

        <div className="rounded-xl border border-app-border p-4">
          <p className="text-sm font-medium text-app-text">Prefer a different approach?</p>
          <p className="mt-0.5 text-xs text-app-muted">{`Reject and tell ${ASSISTANT_BRAND_NAME} what to do instead.`}</p>
          <div className="mt-2.5 flex flex-col gap-2 sm:flex-row">
            <input
              value={alternative}
              onChange={(event) => {
                setAlternative(event.target.value);
                setShowAlternativeError(false);
              }}
              placeholder="e.g. Save it as a draft instead"
              className="min-w-0 flex-1 rounded-md border border-app-border bg-app-surface px-3 py-2 text-sm text-app-text outline-none transition placeholder:text-app-muted focus:border-brand focus:ring-2 focus:ring-brand/20"
            />
            <Button variant="secondary" onClick={submitAlternative}>Send</Button>
          </div>
          {showAlternativeError && (
            <p className="mt-1.5 text-xs text-danger-text">Add instructions before sending.</p>
          )}
        </div>

        <details className="group rounded-xl border border-app-border">
          <summary className="flex cursor-pointer list-none items-center justify-between px-4 py-3 text-sm font-medium text-app-text [&::-webkit-details-marker]:hidden">
            Technical details
            <ChevronDown size={16} className="text-app-muted transition-transform group-open:rotate-180" />
          </summary>
          <pre className="max-h-72 overflow-auto border-t border-app-border bg-app-surface-muted p-4 text-xs text-app-text scrollbar-custom">
            {prettyJson(view.technicalDetails ?? view.rawRequest)}
          </pre>
        </details>
      </div>
    </ModalShell>
  );
};

export default React.memo(ProposeChangesModal);
