import { useFocusEffect } from '@react-navigation/native';
import { CameraView, useCameraPermissions } from 'expo-camera';
import { useKeepAwake } from 'expo-keep-awake';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
  Alert,
  Image,
  Modal,
  Pressable,
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';

import { useApp } from '@/src/app-context';

function PromptModal({
  visible,
  title,
  placeholder,
  value,
  onChange,
  onCancel,
  onConfirm,
}: {
  visible: boolean;
  title: string;
  placeholder: string;
  value: string;
  onChange: (value: string) => void;
  onCancel: () => void;
  onConfirm: () => void;
}) {
  return (
    <Modal visible={visible} transparent animationType="fade" onRequestClose={onCancel}>
      <View style={styles.modalBackdrop}>
        <View style={styles.modalCard}>
          <Text style={styles.modalTitle}>{title}</Text>
          <TextInput
            style={styles.modalInput}
            placeholder={placeholder}
            placeholderTextColor="#6b7280"
            value={value}
            onChangeText={onChange}
            autoCapitalize="none"
          />
          <View style={styles.modalActions}>
            <Pressable style={[styles.modalButton, styles.modalCancel]} onPress={onCancel}>
              <Text style={styles.modalCancelText}>Cancel</Text>
            </Pressable>
            <Pressable style={[styles.modalButton, styles.modalConfirm]} onPress={onConfirm}>
              <Text style={styles.modalConfirmText}>Save</Text>
            </Pressable>
          </View>
        </View>
      </View>
    </Modal>
  );
}

function CameraDashboard() {
  const { state, actions } = useApp();
  const cameraViewRef = useRef<CameraView | null>(null);
  const [permission, requestPermission] = useCameraPermissions();

  // Prevent auto-lock while the camera dashboard is open in the foreground.
  useKeepAwake('securecam-camera-dashboard');

  useEffect(() => {
    actions.setCameraPermissionGranted(Boolean(permission?.granted));
  }, [actions, permission?.granted]);

  useEffect(() => {
    return () => {
      actions.setCameraRef(null);
      actions.setCameraPreviewReady(false);
    };
  }, [actions]);

  return (
    <ScrollView contentContainerStyle={styles.scrollContent}>
      <View style={styles.card}>
        <Text style={styles.cardTitle}>Camera Preview</Text>
        {!permission?.granted ? (
          <View style={styles.permissionBox}>
            <Text style={styles.permissionText}>Camera permission is required to publish live frames.</Text>
            <Pressable style={styles.primaryButton} onPress={() => void requestPermission()}>
              <Text style={styles.primaryButtonText}>Grant Camera Permission</Text>
            </Pressable>
          </View>
        ) : (
          <View style={styles.previewBox}>
            <CameraView
              ref={(ref) => {
                cameraViewRef.current = ref;
                actions.setCameraRef(ref);
              }}
              style={styles.previewCamera}
              facing="back"
              onCameraReady={() => actions.setCameraPreviewReady(true)}
            />
          </View>
        )}
      </View>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>Camera Status</Text>
        <View style={styles.rowBetween}>
          <Text style={styles.label}>Realtime</Text>
          <Text style={[styles.status, state.socketConnected ? styles.online : styles.offline]}>
            {state.socketConnected ? 'ONLINE' : 'OFFLINE'}
          </Text>
        </View>
        <View style={styles.rowBetween}>
          <Text style={styles.label}>Motion</Text>
          <Text style={[styles.status, state.isMotionActive ? styles.online : styles.offline]}>
            {state.isMotionActive ? 'ACTIVE' : 'IDLE'}
          </Text>
        </View>
        <View style={styles.rowBetween}>
          <Text style={styles.label}>Preview</Text>
          <Text style={[styles.status, state.cameraPreviewReady ? styles.online : styles.offline]}>
            {state.cameraPreviewReady ? 'READY' : 'NOT READY'}
          </Text>
        </View>
        <View style={styles.rowBetween}>
          <Text style={styles.label}>Publishing</Text>
          <Text style={[styles.status, state.cameraStatus === 'recording' ? styles.online : styles.offline]}>
            {state.cameraStatus === 'recording' ? 'ACTIVE' : 'IDLE'}
          </Text>
        </View>
      </View>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>Actions</Text>
        {!state.isMotionActive ? (
          <Pressable style={styles.primaryButton} onPress={() => void actions.startMotion()}>
            <Text style={styles.primaryButtonText}>Simulate Motion Event</Text>
          </Pressable>
        ) : (
          <Pressable style={styles.secondaryButton} onPress={() => void actions.endMotion()}>
            <Text style={styles.secondaryButtonText}>Stop Motion Event</Text>
          </Pressable>
        )}

        <Pressable style={styles.secondaryButton} onPress={() => void actions.goOnline()}>
          <Text style={styles.secondaryButtonText}>Reconnect Realtime</Text>
        </Pressable>

        <Text style={styles.infoText}>
          This mobile build remains on the legacy frame-relay path. Add a native WebRTC stack before enabling
          SIMPLE_STREAMING by default.
        </Text>
      </View>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>Logs</Text>
        {state.activityLog.length === 0 ? (
          <Text style={styles.emptyText}>Awaiting events...</Text>
        ) : (
          state.activityLog.map((item) => (
            <Text key={item.id} style={styles.logLine}>
              [{new Date(item.createdAt).toLocaleTimeString()}] {item.type}: {item.message}
            </Text>
          ))
        )}
      </View>
    </ScrollView>
  );
}

function ClientDashboard() {
  const { state, actions } = useApp();
  const [linkModalOpen, setLinkModalOpen] = useState(false);
  const [cameraIdInput, setCameraIdInput] = useState('');
  const [renameTargetId, setRenameTargetId] = useState<string | null>(null);
  const [renameInput, setRenameInput] = useState('');

  const activeCameraLabel = useMemo(() => {
    const linked = state.linkedCameras.find((camera) => camera.cameraDeviceId === state.activeCameraDeviceId);
    return linked?.cameraName || linked?.cameraDeviceId || 'Live Feed Viewer';
  }, [state.activeCameraDeviceId, state.linkedCameras]);

  const isCameraLive = (cameraDeviceId: string) => {
    const sessionId = state.cameraSessions?.[cameraDeviceId];
    if (!sessionId) return false;
    return state.connectedStreamSessionIds.includes(sessionId);
  };

  const openRenameModal = (cameraDeviceId: string, currentName?: string | null) => {
    setRenameTargetId(cameraDeviceId);
    setRenameInput(currentName || '');
  };

  const submitRename = async () => {
    if (!renameTargetId) return;
    await actions.renameLinkedCamera(renameTargetId, renameInput);
    setRenameTargetId(null);
    setRenameInput('');
  };

  return (
    <>
      <ScrollView contentContainerStyle={styles.scrollContent}>
        <View style={styles.rowBetween}>
          <Text style={styles.screenTitle}>Client Dashboard</Text>
          <View style={styles.rowGap}>
            <Pressable style={styles.outlineButton} onPress={() => setLinkModalOpen(true)}>
              <Text style={styles.outlineButtonText}>Link Camera</Text>
            </Pressable>
            <Pressable style={styles.iconButton} onPress={() => void actions.refreshClientData()}>
              <Text style={styles.iconButtonText}>R</Text>
            </Pressable>
          </View>
        </View>

        <View style={styles.card}>
          <Text style={styles.cardTitle}>Your Cameras</Text>
          <ScrollView horizontal contentContainerStyle={styles.cameraRow} showsHorizontalScrollIndicator={false}>
            {state.linkedCameras.length === 0 ? (
              <View style={styles.emptyCameraCard}>
                <Text style={styles.emptyText}>No cameras linked yet</Text>
              </View>
            ) : (
              state.linkedCameras.map((link) => {
                const selected = state.activeCameraDeviceId === link.cameraDeviceId;
                const live = isCameraLive(link.cameraDeviceId);
                return (
                  <View
                    key={link.id}
                    style={[styles.cameraCard, selected ? styles.cameraCardSelected : null]}>
                    <Text style={styles.cameraName}>{link.cameraName || link.cameraDeviceId}</Text>
                    <Text style={[styles.cameraStatus, link.cameraStatus === 'online' ? styles.online : styles.offline]}>
                      {(link.cameraStatus || 'offline').toUpperCase()}
                    </Text>
                    <Text style={styles.cameraSubtext}>{live ? 'Live stream active' : 'Tap view to request stream'}</Text>

                    <View style={styles.cameraActionsRow}>
                      <Pressable style={styles.smallButton} onPress={() => void actions.selectCamera(link.cameraDeviceId)}>
                        <Text style={styles.smallButtonText}>View</Text>
                      </Pressable>
                      <Pressable
                        style={styles.smallButton}
                        onPress={() => openRenameModal(link.cameraDeviceId, link.cameraName)}>
                        <Text style={styles.smallButtonText}>Rename</Text>
                      </Pressable>
                      <Pressable
                        style={[styles.smallButton, styles.smallDangerButton]}
                        onPress={() => {
                          Alert.alert(
                            'Remove Camera',
                            `Remove \"${link.cameraName || link.cameraDeviceId}\" from linked cameras?`,
                            [
                              { text: 'Cancel', style: 'cancel' },
                              {
                                text: 'Delete',
                                style: 'destructive',
                                onPress: () => {
                                  void actions.deleteLinkedCamera(link.id);
                                },
                              },
                            ],
                          );
                        }}>
                        <Text style={[styles.smallButtonText, styles.smallDangerText]}>Delete</Text>
                      </Pressable>
                    </View>
                  </View>
                );
              })
            )}
          </ScrollView>
        </View>

        {state.activeCameraDeviceId ? (
          <View style={styles.card}>
            <View style={styles.rowBetween}>
              <Text style={styles.cardTitle}>Live Feed: {activeCameraLabel}</Text>
              <Pressable style={styles.iconButton} onPress={actions.closeStreamViewer}>
                <Text style={styles.iconButtonText}>X</Text>
              </Pressable>
            </View>

            <View style={styles.streamBox}>
              {state.clientStreamMode === 'image' && state.clientFallbackFrame ? (
                <Image source={{ uri: state.clientFallbackFrame }} style={styles.streamImage} resizeMode="contain" />
              ) : (
                <Text style={styles.streamPlaceholder}>{state.clientPlaceholderText}</Text>
              )}
            </View>
          </View>
        ) : null}

        <View style={styles.card}>
          <Text style={styles.cardTitle}>Recent Recordings</Text>
          {state.recordings.length === 0 ? (
            <Text style={styles.emptyText}>No recordings found</Text>
          ) : (
            state.recordings.slice(0, 5).map((recording) => (
              <View key={recording.id} style={styles.recordingRow}>
                <View style={{ flex: 1 }}>
                  <Text style={styles.recordingTitle}>{new Date(recording.createdAt).toLocaleString()}</Text>
                  <Text style={styles.recordingMeta}>
                    {recording.durationSeconds != null ? `${recording.durationSeconds}s` : 'Duration pending'} -{' '}
                    {recording.status ?? 'unknown'}
                  </Text>
                </View>
                <Pressable
                  style={styles.smallButton}
                  disabled={recording.status !== 'ready'}
                  onPress={() => void actions.openRecording(recording.id)}>
                  <Text style={styles.smallButtonText}>Open</Text>
                </Pressable>
              </View>
            ))
          )}
        </View>
      </ScrollView>

      <PromptModal
        visible={linkModalOpen}
        title="Link Camera"
        placeholder="Camera Device ID"
        value={cameraIdInput}
        onChange={setCameraIdInput}
        onCancel={() => {
          setLinkModalOpen(false);
          setCameraIdInput('');
        }}
        onConfirm={() => {
          void actions.linkCamera(cameraIdInput);
          setLinkModalOpen(false);
          setCameraIdInput('');
        }}
      />

      <PromptModal
        visible={Boolean(renameTargetId)}
        title="Rename Camera"
        placeholder="Camera name"
        value={renameInput}
        onChange={setRenameInput}
        onCancel={() => {
          setRenameTargetId(null);
          setRenameInput('');
        }}
        onConfirm={() => {
          void submitRename();
        }}
      />
    </>
  );
}

export default function DashboardScreen() {
  const { state, actions } = useApp();

  useFocusEffect(
    React.useCallback(() => {
      actions.setPage(state.device?.role === 'camera' ? 'camera' : 'client');
      return undefined;
    }, [actions, state.device?.role]),
  );

  return <SafeAreaView style={styles.safe}>{state.device?.role === 'camera' ? <CameraDashboard /> : <ClientDashboard />}</SafeAreaView>;
}

const styles = StyleSheet.create({
  safe: {
    flex: 1,
    backgroundColor: '#0a0a0c',
  },
  scrollContent: {
    padding: 14,
    gap: 12,
  },
  screenTitle: {
    color: '#f9fafb',
    fontSize: 22,
    fontWeight: '700',
  },
  rowBetween: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 10,
  },
  rowGap: {
    flexDirection: 'row',
    gap: 8,
    alignItems: 'center',
  },
  card: {
    borderRadius: 16,
    padding: 14,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
    backgroundColor: '#111218',
    gap: 10,
  },
  cardTitle: {
    color: '#f9fafb',
    fontSize: 15,
    fontWeight: '600',
  },
  previewBox: {
    height: 220,
    borderRadius: 12,
    overflow: 'hidden',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.1)',
    backgroundColor: '#08090d',
  },
  previewCamera: {
    flex: 1,
  },
  permissionBox: {
    borderRadius: 12,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.1)',
    backgroundColor: '#08090d',
    padding: 12,
    gap: 10,
  },
  permissionText: {
    color: '#9ca3af',
    fontSize: 12,
    lineHeight: 18,
  },
  label: {
    color: '#9ca3af',
    fontSize: 12,
  },
  status: {
    fontSize: 12,
    fontWeight: '700',
  },
  online: {
    color: '#34d399',
  },
  offline: {
    color: '#f87171',
  },
  primaryButton: {
    height: 44,
    borderRadius: 10,
    backgroundColor: '#2563eb',
    alignItems: 'center',
    justifyContent: 'center',
  },
  primaryButtonText: {
    color: '#f9fafb',
    fontWeight: '700',
    fontSize: 14,
  },
  secondaryButton: {
    height: 44,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.12)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  secondaryButtonText: {
    color: '#d1d5db',
    fontWeight: '600',
    fontSize: 13,
  },
  outlineButton: {
    height: 36,
    borderRadius: 9,
    paddingHorizontal: 12,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.18)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  outlineButtonText: {
    color: '#d1d5db',
    fontSize: 12,
    fontWeight: '600',
  },
  iconButton: {
    height: 36,
    width: 36,
    borderRadius: 9,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.18)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  iconButtonText: {
    color: '#d1d5db',
    fontSize: 12,
    fontWeight: '700',
  },
  infoText: {
    color: '#9ca3af',
    fontSize: 12,
    lineHeight: 18,
  },
  emptyText: {
    color: '#6b7280',
    fontSize: 12,
  },
  logLine: {
    color: '#9ca3af',
    fontSize: 12,
    lineHeight: 18,
  },
  cameraRow: {
    gap: 10,
  },
  emptyCameraCard: {
    borderRadius: 12,
    borderWidth: 1,
    borderStyle: 'dashed',
    borderColor: 'rgba(255,255,255,0.2)',
    padding: 16,
    minWidth: 240,
  },
  cameraCard: {
    minWidth: 260,
    borderRadius: 12,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
    padding: 12,
    backgroundColor: '#0d0f15',
    gap: 6,
  },
  cameraCardSelected: {
    borderColor: '#3b82f6',
    backgroundColor: '#111b2f',
  },
  cameraName: {
    color: '#f3f4f6',
    fontWeight: '600',
    fontSize: 13,
  },
  cameraStatus: {
    fontSize: 11,
    fontWeight: '700',
  },
  cameraSubtext: {
    color: '#9ca3af',
    fontSize: 11,
    marginBottom: 4,
  },
  cameraActionsRow: {
    flexDirection: 'row',
    gap: 6,
  },
  smallButton: {
    borderRadius: 8,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.16)',
    paddingHorizontal: 10,
    height: 30,
    alignItems: 'center',
    justifyContent: 'center',
  },
  smallButtonText: {
    color: '#d1d5db',
    fontSize: 11,
    fontWeight: '600',
  },
  smallDangerButton: {
    borderColor: 'rgba(248,113,113,0.4)',
  },
  smallDangerText: {
    color: '#fca5a5',
  },
  streamBox: {
    height: 220,
    borderRadius: 12,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.1)',
    backgroundColor: '#08090d',
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden',
  },
  streamImage: {
    width: '100%',
    height: '100%',
  },
  streamPlaceholder: {
    color: '#6b7280',
    fontWeight: '600',
  },
  recordingRow: {
    borderRadius: 10,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
    backgroundColor: '#0d0f15',
    padding: 10,
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  recordingTitle: {
    color: '#e5e7eb',
    fontSize: 12,
    fontWeight: '500',
  },
  recordingMeta: {
    color: '#6b7280',
    fontSize: 11,
    marginTop: 2,
  },
  modalBackdrop: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.7)',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 16,
  },
  modalCard: {
    width: '100%',
    maxWidth: 360,
    borderRadius: 14,
    padding: 14,
    backgroundColor: '#111218',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.1)',
    gap: 10,
  },
  modalTitle: {
    color: '#f3f4f6',
    fontSize: 16,
    fontWeight: '700',
  },
  modalInput: {
    height: 46,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.14)',
    backgroundColor: '#0a0a0e',
    color: '#f3f4f6',
    paddingHorizontal: 10,
  },
  modalActions: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    gap: 8,
  },
  modalButton: {
    height: 36,
    borderRadius: 8,
    minWidth: 76,
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 10,
  },
  modalCancel: {
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.16)',
  },
  modalConfirm: {
    backgroundColor: '#2563eb',
  },
  modalCancelText: {
    color: '#d1d5db',
    fontWeight: '600',
  },
  modalConfirmText: {
    color: '#f9fafb',
    fontWeight: '700',
  },
});
