import { useMemo, useState } from 'react'
import { useTranslation } from '../../i18n'
import { computerUseApi } from '../../api/computerUse'
import { useChatStore } from '../../stores/chatStore'
import type {
  ComputerUsePermissionRequest,
  ComputerUsePermissionResponse,
} from '../../types/chat'
import { Button } from '../shared/Button'
import { Modal } from '../shared/Modal'

type Props = {
  sessionId: string
  request: ComputerUsePermissionRequest | null
}

const DEFAULT_GRANT_FLAGS = {
  clipboardRead: false,
  clipboardWrite: false,
  systemKeyCombos: false,
} as const

function denyAllResponse(): ComputerUsePermissionResponse {
  return {
    granted: [],
    denied: [],
    flags: { ...DEFAULT_GRANT_FLAGS },
    userConsented: false,
  }
}

function buildAllowResponse(
  request: ComputerUsePermissionRequest,
): ComputerUsePermissionResponse {
  const now = Date.now()
  const granted = request.apps.flatMap((app) => {
    if (!app.resolved || app.alreadyGranted) return []
    return [{
      bundleId: app.resolved.bundleId,
      displayName: app.resolved.displayName,
      grantedAt: now,
      tier: app.proposedTier,
    }]
  })

  const denied = request.apps.flatMap((app) => {
    if (app.resolved) return []
    return [{
      bundleId: app.requestedName,
      reason: 'not_installed' as const,
    }]
  })

  const flags = {
    ...DEFAULT_GRANT_FLAGS,
    ...Object.fromEntries(
      Object.entries(request.requestedFlags).filter(([, value]) => value === true),
    ),
  }

  return {
    granted,
    denied,
    flags,
    userConsented: true,
  }
}

export function ComputerUsePermissionModal({ sessionId, request }: Props) {
  const t = useTranslation()
  const respondToComputerUsePermission = useChatStore(
    (s) => s.respondToComputerUsePermission,
  )
  const [openingPane, setOpeningPane] = useState<
    'Privacy_Accessibility' | 'Privacy_ScreenCapture' | null
  >(null)

  const requestedFlags = useMemo(
    () =>
      request
        ? Object.entries(request.requestedFlags)
            .filter(([, enabled]) => enabled)
            .map(([flag]) => flag)
        : [],
    [request],
  )

  if (!request) return null

  const handleDeny = () => {
    respondToComputerUsePermission(
      sessionId,
      request.requestId,
      denyAllResponse(),
    )
  }

  const handleAllow = () => {
    respondToComputerUsePermission(
      sessionId,
      request.requestId,
      buildAllowResponse(request),
    )
  }

  const openSettings = async (
    pane: 'Privacy_Accessibility' | 'Privacy_ScreenCapture',
  ) => {
    setOpeningPane(pane)
    try {
      await computerUseApi.openSettings(pane)
    } finally {
      setOpeningPane(null)
    }
  }

  const tccState = request.tccState

  return (
    <Modal
      open
      onClose={handleDeny}
      title={
        tccState
          ? t('computerUseApproval.titleTcc')
          : t('computerUseApproval.titleApps')
      }
      width={640}
      footer={
        tccState ? (
          <Button variant="ghost" onClick={handleDeny}>
            {t('computerUseApproval.deny')}
          </Button>
        ) : (
          <>
            <Button variant="ghost" onClick={handleDeny}>
              {t('computerUseApproval.deny')}
            </Button>
            <Button variant="primary" onClick={handleAllow}>
              {t('computerUseApproval.allow')}
            </Button>
          </>
        )
      }
    >
      {tccState ? (
        <div className="space-y-4">
          <p className="text-sm text-[var(--color-text-secondary)]">
            {t('computerUseApproval.tccHint')}
          </p>

          <div className="space-y-3">
            <PermissionRow
              label={t('computerUseApproval.accessibility')}
              granted={tccState.accessibility}
              actionLabel={t('computerUseApproval.openAccessibility')}
              actionLoading={openingPane === 'Privacy_Accessibility'}
              onAction={() => openSettings('Privacy_Accessibility')}
            />
            <PermissionRow
              label={t('computerUseApproval.screenRecording')}
              granted={tccState.screenRecording}
              actionLabel={t('computerUseApproval.openScreenRecording')}
              actionLoading={openingPane === 'Privacy_ScreenCapture'}
              onAction={() => openSettings('Privacy_ScreenCapture')}
            />
          </div>

          <div className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3 text-xs text-[var(--color-text-tertiary)]">
            {t('computerUseApproval.tryAgainHint')}
          </div>

          <div className="flex justify-end">
            <Button variant="secondary" onClick={handleDeny}>
              {t('computerUseApproval.tryAgain')}
            </Button>
          </div>
        </div>
      ) : (
        <div className="space-y-4">
          {request.reason ? (
            <div className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3">
              <div className="text-xs font-semibold uppercase tracking-wide text-[var(--color-text-tertiary)]">
                {t('computerUseApproval.reason')}
              </div>
              <div className="mt-1 text-sm text-[var(--color-text-primary)]">
                {request.reason}
              </div>
            </div>
          ) : null}

          <div className="space-y-2">
            {request.apps.map((app) => {
              const resolved = app.resolved
              return (
                <div
                  key={resolved?.bundleId ?? app.requestedName}
                  className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3"
                >
                  <div className="flex items-start justify-between gap-3">
                    <div>
                      <div className="text-sm font-semibold text-[var(--color-text-primary)]">
                        {resolved?.displayName ?? app.requestedName}
                      </div>
                      <div className="mt-1 text-xs text-[var(--color-text-tertiary)]">
                        {resolved?.bundleId ?? t('computerUseApproval.notInstalled')}
                      </div>
                    </div>
                    <span className="rounded-full bg-[var(--color-surface-container)] px-2 py-1 text-[10px] font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]">
                      {app.proposedTier}
                    </span>
                  </div>

                  {!resolved ? (
                    <p className="mt-2 text-xs text-[var(--color-error)]">
                      {t('computerUseApproval.notInstalled')}
                    </p>
                  ) : null}

                  {app.alreadyGranted ? (
                    <p className="mt-2 text-xs text-[var(--color-success)]">
                      {t('computerUseApproval.alreadyGranted')}
                    </p>
                  ) : null}

                  {app.isSentinel ? (
                    <p className="mt-2 text-xs text-[var(--color-warning)]">
                      {t('computerUseApproval.sensitiveApp')}
                    </p>
                  ) : null}
                </div>
              )
            })}
          </div>

          {requestedFlags.length > 0 ? (
            <div className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3">
              <div className="text-xs font-semibold uppercase tracking-wide text-[var(--color-text-tertiary)]">
                {t('computerUseApproval.alsoRequested')}
              </div>
              <div className="mt-2 flex flex-wrap gap-2">
                {requestedFlags.map((flag) => (
                  <span
                    key={flag}
                    className="rounded-full bg-[var(--color-surface-container)] px-2 py-1 text-[11px] text-[var(--color-text-secondary)]"
                  >
                    {flag}
                  </span>
                ))}
              </div>
            </div>
          ) : null}

          {request.willHide && request.willHide.length > 0 ? (
            <div className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3 text-sm text-[var(--color-text-secondary)]">
              {request.autoUnhideEnabled
                ? t('computerUseApproval.hideWhileWorkingRestore', {
                    count: request.willHide.length,
                  })
                : t('computerUseApproval.hideWhileWorking', {
                    count: request.willHide.length,
                  })}
            </div>
          ) : null}
        </div>
      )}
    </Modal>
  )
}

function PermissionRow({
  label,
  granted,
  actionLabel,
  actionLoading,
  onAction,
}: {
  label: string
  granted: boolean
  actionLabel: string
  actionLoading: boolean
  onAction: () => void
}) {
  const t = useTranslation()

  return (
    <div className="flex items-center justify-between gap-4 rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-3">
      <div>
        <div className="text-sm font-semibold text-[var(--color-text-primary)]">
          {label}
        </div>
        <div className="mt-1 text-xs text-[var(--color-text-tertiary)]">
          {granted
            ? t('computerUseApproval.granted')
            : t('computerUseApproval.notGranted')}
        </div>
      </div>

      {!granted ? (
        <Button
          variant="secondary"
          size="sm"
          loading={actionLoading}
          onClick={onAction}
        >
          {actionLabel}
        </Button>
      ) : null}
    </div>
  )
}
