import React, { useState, useCallback, useEffect, useRef } from 'react';
import {
  View, Text, ScrollView, StyleSheet, TextInput, TouchableOpacity, RefreshControl, Modal, FlatList, Image, ActivityIndicator,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';
import * as Location from 'expo-location';
import * as ImagePicker from 'expo-image-picker';
import { useResponsive } from '../../hooks/useResponsive';
import { ScreenContainer } from '../../components/layout/ScreenContainer';
import { AnimatedCard } from '../../components/ui/AnimatedCard';
import { StatusBadge } from '../../components/common/StatusBadge';
import { ConfirmDialog } from '../../components/ui/ConfirmDialog';
import { jobService } from '../../services/jobService';
import { adminService } from '../../services/adminService';
import { materialService } from '../../services/materialService';
import { checkinService } from '../../services/checkinService';
import { geofenceService } from '../../services/geofenceService';
import { mediaService, getMediaUrl } from '../../services/mediaService';
import { useAuth } from '../../hooks/useAuth';
import { useToast } from '../../context/ToastContext';
import { Job, JobNote, JobAssignment, User, MaterialRequest, Material, JobMedia } from '../../types';
import { colors, spacing, radii } from '../../theme';

export default function JobDetailScreen() {
  const navigation = useNavigation<any>();
  const route = useRoute<any>();
  const { jobId } = route.params;
  const { user, hasPermission } = useAuth();
  const { toast } = useToast();
  const { isPhone, contentPadding, fontSize } = useResponsive();

  const [job, setJob] = useState<Job | null>(null);
  const [notes, setNotes] = useState<JobNote[]>([]);
  const [assignments, setAssignments] = useState<JobAssignment[]>([]);
  const [users, setUsers] = useState<User[]>([]);
  const [jobMaterials, setJobMaterials] = useState<MaterialRequest[]>([]);
  const [availableMaterials, setAvailableMaterials] = useState<Material[]>([]);
  const [jobMedia, setJobMedia] = useState<JobMedia[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  const [newNote, setNewNote] = useState('');
  const [submittingNote, setSubmittingNote] = useState(false);
  const [showAssignModal, setShowAssignModal] = useState(false);
  const [assigning, setAssigning] = useState(false);
  const [showMaterialModal, setShowMaterialModal] = useState(false);
  const [showAssignMaterialModal, setShowAssignMaterialModal] = useState(false);
  const [selectedMaterialId, setSelectedMaterialId] = useState<number | null>(null);
  const [materialQuantity, setMaterialQuantity] = useState('1');
  const [materialRemarks, setMaterialRemarks] = useState('');
  const [assignTarget, setAssignTarget] = useState<MaterialRequest | null>(null);
  const [assigningMaterial, setAssigningMaterial] = useState(false);
  const [requestingMaterial, setRequestingMaterial] = useState(false);
  const [returnTarget, setReturnTarget] = useState<MaterialRequest | null>(null);
  const [returning, setReturning] = useState(false);
  const [deleteJobTarget, setDeleteJobTarget] = useState(false);
  const [deletingJob, setDeletingJob] = useState(false);
  const [deleteMemberTarget, setDeleteMemberTarget] = useState<JobAssignment | null>(null);
  const [deletingMember, setDeletingMember] = useState(false);
  const [deleteMaterialTarget, setDeleteMaterialTarget] = useState<MaterialRequest | null>(null);
  const [deletingMaterial, setDeletingMaterial] = useState(false);

  const [currentLocation, setCurrentLocation] = useState<Location.LocationObject | null>(null);
  const [locationAddress, setLocationAddress] = useState<string>('');
  const [locationCoords, setLocationCoords] = useState<string>('');
  const [locationLoading, setLocationLoading] = useState(true);
  const [isCheckedIn, setIsCheckedIn] = useState(false);
  const [isCheckingIn, setIsCheckingIn] = useState(false);
  const [checkinLocation, setCheckinLocation] = useState<string>('');
  const [checkingOut, setCheckingOut] = useState(false);
  const [uploadingPhoto, setUploadingPhoto] = useState(false);
  const [geofenceResult, setGeofenceResult] = useState<{ inside: boolean; distance_meters?: number; geofence_id?: number; name?: string; radius?: number } | null>(null);
  const [refreshingLocation, setRefreshingLocation] = useState(false);
  const locationFetched = useRef(false);

  useEffect(() => {
    if (!locationFetched.current) {
      locationFetched.current = true;
      autoFetchAndCheckin();
    }
  }, [jobId]);

  const autoFetchAndCheckin = async (retryCount = 0) => {
    setLocationLoading(true);
    try {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setLocationAddress('Location permission denied');
        setLocationLoading(false);
        return;
      }

      let loc: Location.LocationObject | null = null;
      try {
        loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High });
      } catch {
        if (retryCount < 2) {
          try {
            loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced });
          } catch {}
        }
        if (!loc && retryCount < 2) {
          setTimeout(() => autoFetchAndCheckin(retryCount + 1), 1500);
          return;
        }
        if (!loc) {
          setLocationAddress('Failed to get location');
          setLocationLoading(false);
          return;
        }
      }

      setCurrentLocation(loc);

      const [addr] = await Location.reverseGeocodeAsync({
        latitude: loc.coords.latitude,
        longitude: loc.coords.longitude,
      });
      const coordStr = `${loc.coords.latitude.toFixed(4)}, ${loc.coords.longitude.toFixed(4)}`;
      let addressStr = coordStr;
      if (addr) {
        const parts = [addr.name, addr.street, addr.city, addr.region, addr.postalCode].filter(Boolean);
        addressStr = parts.join(', ') || coordStr;
      }
      setLocationAddress(addressStr);
      setLocationCoords(coordStr);

      const currentJob = await jobService.get(jobId);
      const canCheckin = ['DRAFT', 'APPROVED', 'ASSIGNED'].includes(currentJob.status);

      if (canCheckin && hasPermission('job.update')) {
        let inside = true;
        let distance: number | null = null;
        if (currentJob.required_geofence_id) {
          try {
            const gfResult = await geofenceService.check(loc.coords.latitude, loc.coords.longitude);
            inside = gfResult.inside;
            distance = gfResult.distance_meters ?? null;
            setGeofenceResult(gfResult);
          } catch {}
        } else {
          setGeofenceResult({ inside: true });
        }

        try {
          await checkinService.checkIn(jobId, {
            latitude: loc.coords.latitude,
            longitude: loc.coords.longitude,
            accuracy: loc.coords.accuracy || undefined,
            manual_override: !inside,
            override_reason: !inside ? 'Auto check-in: outside geofence' : undefined,
          });
          setIsCheckedIn(true);
          setCheckinLocation(addressStr);
          if (inside) {
            toast('Checked in successfully', 'success');
          } else {
            toast(`Checked in (outside geofence${distance != null ? `, ${Math.round(distance)}m away` : ''})`, 'success');
          }
          loadJob();
        } catch {
          setIsCheckedIn(false);
        }
      } else if (currentJob.status === 'CHECKED_IN' || currentJob.status === 'IN_PROGRESS') {
        setIsCheckedIn(true);
      }
    } catch {
      setLocationAddress('Failed to get location');
    } finally {
      setLocationLoading(false);
    }
  };

  const refreshLocation = async () => {
    setRefreshingLocation(true);
    try {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        toast('Location permission denied', 'error');
        return;
      }

      let loc: Location.LocationObject | null = null;
      try {
        loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High });
      } catch {
        try {
          loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced });
        } catch {}
      }
      if (!loc) {
        toast('Failed to get location', 'error');
        return;
      }

      setCurrentLocation(loc);

      const [addr] = await Location.reverseGeocodeAsync({
        latitude: loc.coords.latitude,
        longitude: loc.coords.longitude,
      });
      const coordStr = `${loc.coords.latitude.toFixed(4)}, ${loc.coords.longitude.toFixed(4)}`;
      let addressStr = coordStr;
      if (addr) {
        const parts = [addr.name, addr.street, addr.city, addr.region, addr.postalCode].filter(Boolean);
        addressStr = parts.join(', ') || coordStr;
      }
      setLocationAddress(addressStr);
      setLocationCoords(coordStr);

      if (job?.required_geofence_id) {
        try {
          const gfResult = await geofenceService.check(loc.coords.latitude, loc.coords.longitude);
          setGeofenceResult(gfResult);
        } catch {}
      }

      toast('Location updated', 'success');
    } catch {
      toast('Failed to get location', 'error');
    } finally {
      setRefreshingLocation(false);
    }
  };

  const loadJob = async () => {
    try {
      const [jobData, notesData, assignmentsData, materialsData, mediaData] = await Promise.all([
        jobService.get(jobId),
        jobService.listNotes(jobId),
        jobService.assignments(jobId),
        materialService.jobMaterials(jobId).catch(() => []),
        mediaService.list(jobId).catch(() => []),
      ]);
      setJob(jobData);
      setNotes(notesData);
      setAssignments(assignmentsData);
      setJobMaterials(materialsData);
      setJobMedia(mediaData);
      if (jobData.status === 'CHECKED_IN' || jobData.status === 'IN_PROGRESS') {
        setIsCheckedIn(true);
      } else {
        setIsCheckedIn(false);
      }
    } catch (error) {
      console.error('Failed to load job:', error);
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  const loadUsers = async () => {
    try {
      const data = await adminService.users();
      setUsers(data);
    } catch {}
  };

  useFocusEffect(useCallback(() => { loadJob(); }, [jobId]));

  const onRefresh = () => { setRefreshing(true); loadJob(); };

  const handleStatusChange = async (newStatus: string) => {
    try {
      await jobService.changeStatus(jobId, newStatus);
      toast(`Status changed to ${newStatus.replace(/_/g, ' ')}`, 'success');
      loadJob();
    } catch (error: any) {
      toast(error.response?.data?.error || 'Failed to change status', 'error');
    }
  };

  const handleCheckOut = async () => {
    setCheckingOut(true);
    try {
      let loc = currentLocation;
      if (!loc) {
        try {
          loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced });
          setCurrentLocation(loc);
        } catch {}
      }
      if (!loc) {
        toast('Location not available', 'error');
        setCheckingOut(false);
        return;
      }
      await checkinService.checkOut(jobId, {
        latitude: loc.coords.latitude,
        longitude: loc.coords.longitude,
        accuracy: loc.coords.accuracy || undefined,
      });
      setIsCheckedIn(false);
      toast('Checked out successfully', 'success');
      loadJob();
    } catch (error: any) {
      toast(error.response?.data?.error || 'Check-out failed', 'error');
    } finally {
      setCheckingOut(false);
    }
  };

  const handleTakePhoto = async (mediaType: 'BEFORE' | 'DURING' | 'AFTER') => {
    const perm = await ImagePicker.requestCameraPermissionsAsync();
    if (!perm.granted) {
      toast('Camera permission required', 'error');
      return;
    }
    const result = await ImagePicker.launchCameraAsync({
      mediaTypes: ['images'],
      quality: 0.8,
      allowsEditing: true,
    });
    if (result.canceled || !result.assets?.[0]) return;

    setUploadingPhoto(true);
    try {
      const asset = result.assets[0];
      const formData = new FormData();
      formData.append('photo', {
        uri: asset.uri,
        name: `photo_${Date.now()}.jpg`,
        type: 'image/jpeg',
      } as any);
      formData.append('media_type', mediaType);
      if (currentLocation) {
        formData.append('latitude', String(currentLocation.coords.latitude));
        formData.append('longitude', String(currentLocation.coords.longitude));
        formData.append('gps_accuracy', String(currentLocation.coords.accuracy || 0));
      }
      formData.append('captured_at', new Date().toISOString());

      await mediaService.upload(jobId, formData);
      toast(`${mediaType.toLowerCase()} photo uploaded`, 'success');
      loadJob();
    } catch {
      toast('Failed to upload photo', 'error');
    } finally {
      setUploadingPhoto(false);
    }
  };

  const handleAddNote = async () => {
    if (!newNote.trim()) return;
    setSubmittingNote(true);
    try {
      await jobService.addNote(jobId, newNote.trim());
      setNewNote('');
      toast('Note added', 'success');
      loadJob();
    } catch {
      toast('Failed to add note', 'error');
    } finally {
      setSubmittingNote(false);
    }
  };

  const handleDeleteJob = async () => {
    setDeletingJob(true);
    try {
      await jobService.remove(jobId);
      toast('Job deleted', 'success');
      navigation.goBack();
    } catch {
      toast('Failed to delete job', 'error');
    } finally {
      setDeletingJob(false);
      setDeleteJobTarget(false);
    }
  };

  const handleRemoveMember = async () => {
    if (!deleteMemberTarget) return;
    setDeletingMember(true);
    try {
      await jobService.removeMember(jobId, deleteMemberTarget.user_id);
      toast('Member removed', 'success');
      setDeleteMemberTarget(null);
      loadJob();
    } catch {
      toast('Failed to remove member', 'error');
    } finally {
      setDeletingMember(false);
    }
  };

  const handleRemoveMaterial = async () => {
    if (!deleteMaterialTarget) return;
    setDeletingMaterial(true);
    try {
      await materialService.removeMaterialFromJob(deleteMaterialTarget.id);
      toast('Material removed from job', 'success');
      setDeleteMaterialTarget(null);
      loadJob();
    } catch (e: any) {
      toast(e.response?.data?.message || 'Failed to remove material', 'error');
    } finally {
      setDeletingMaterial(false);
    }
  };

  const handleAssign = async (userId: number) => {
    setAssigning(true);
    try {
      await jobService.assign(jobId, userId);
      toast('User assigned successfully', 'success');
      setShowAssignModal(false);
      loadJob();
    } catch (error: any) {
      toast(error.response?.data?.error || 'Failed to assign user', 'error');
    } finally {
      setAssigning(false);
    }
  };

  const openAssignModal = async () => {
    await loadUsers();
    setShowAssignModal(true);
  };

  const loadMaterials = async () => {
    try {
      const data = await materialService.list();
      setAvailableMaterials(data);
    } catch {}
  };

  const handleRequestMaterial = async () => {
    if (!selectedMaterialId || !materialQuantity) return;
    setRequestingMaterial(true);
    try {
      await materialService.request({
        job_id: jobId,
        material_id: selectedMaterialId,
        quantity: parseInt(materialQuantity) || 1,
        remarks: materialRemarks || undefined,
      });
      toast('Material requested', 'success');
      setShowMaterialModal(false);
      setSelectedMaterialId(null);
      setMaterialQuantity('1');
      setMaterialRemarks('');
      loadJob();
    } catch {
      toast('Failed to request material', 'error');
    } finally {
      setRequestingMaterial(false);
    }
  };

  const openAssignMaterial = (item: MaterialRequest) => {
    setAssignTarget(item);
    setShowAssignMaterialModal(true);
  };

  const handleAssignMaterial = async (userId: number) => {
    if (!assignTarget) return;
    setAssigningMaterial(true);
    try {
      await materialService.approve(assignTarget.id);
      await materialService.assignToPerson(assignTarget.id, userId);
      toast('Material assigned', 'success');
      setShowAssignMaterialModal(false);
      setAssignTarget(null);
      loadJob();
    } catch {
      toast('Failed to assign material', 'error');
    } finally {
      setAssigningMaterial(false);
    }
  };

  const handleReturnMaterial = async () => {
    if (!returnTarget) return;
    setReturning(true);
    try {
      await materialService.returnToStock(returnTarget.id);
      toast('Material returned to stock', 'success');
      setReturnTarget(null);
      loadJob();
    } catch {
      toast('Failed to return material', 'error');
    } finally {
      setReturning(false);
    }
  };

  if (loading || !job) return null;

  const statusActions: Record<string, string[]> = {
    DRAFT: ['APPROVED'],
    APPROVED: ['ASSIGNED'],
    IN_PROGRESS: ['COMPLETED', 'ON_HOLD'],
    ON_HOLD: ['IN_PROGRESS'],
  };

  const assignedUserIds = assignments.map(a => a.user_id);
  const availableUsers = users.filter(u => !assignedUserIds.includes(u.id));

  return (
    <>
      <ScreenContainer
        title={job.title}
        subtitle={job.job_number}
        onBack={() => navigation.goBack()}
        rightAction={hasPermission('job.delete') ? { icon: 'trash-outline', onPress: () => setDeleteJobTarget(true) } : undefined}
        loading={false}
        refreshing={refreshing}
        onRefresh={onRefresh}
        scroll={true}
        contentPadding={contentPadding}
      >
        {/* Location Header */}
        <AnimatedCard delay={0}>
          <View style={styles.locationHeader}>
            <View style={[styles.locationIconWrap, { backgroundColor: locationAddress ? colors.success[50] : colors.gray[100] }]}>
              <Ionicons name="location" size={18} color={locationAddress ? colors.success[600] : colors.gray[400]} />
            </View>
            <View style={{ flex: 1 }}>
              {locationLoading ? (
                <View style={{ flexDirection: 'row', alignItems: 'center', gap: spacing.xs }}>
                  <ActivityIndicator size="small" color={colors.primary[500]} />
                  <Text style={{ color: colors.gray[400], fontSize: fontSize.caption }}>Fetching location...</Text>
                </View>
              ) : (
                <>
                  <Text style={[styles.addressText, { fontSize: fontSize.caption }]} numberOfLines={2}>
                    {locationAddress || 'Location not available'}
                  </Text>
                  {locationCoords && locationCoords !== locationAddress && (
                    <Text style={{ color: colors.gray[400], fontSize: 10, fontFamily: 'monospace', marginTop: 2 }} numberOfLines={1}>
                      {locationCoords}
                    </Text>
                  )}
                </>
              )}
            </View>
            <TouchableOpacity onPress={refreshLocation} disabled={refreshingLocation || locationLoading} style={{ padding: spacing.xs }} activeOpacity={0.6}>
              <Ionicons name={refreshingLocation ? 'refresh' : 'refresh-outline'} size={16} color={colors.primary[600]} />
            </TouchableOpacity>
          </View>

          <View style={styles.headerRow}>
            <StatusBadge status={job.status} size="md" />
            {isCheckedIn && (
              <View style={[styles.checkedInBadge, { backgroundColor: colors.success[50] }]}>
                <Ionicons name="checkmark-circle" size={14} color={colors.success[600]} />
                <Text style={{ color: colors.success[700], fontWeight: '600', fontSize: fontSize.caption }}>Checked In</Text>
              </View>
            )}
          </View>

          {job.description && <Text style={[styles.description, { fontSize: fontSize.body, lineHeight: 20, marginBottom: spacing.md }]}>{job.description}</Text>}

          <View style={[styles.metaRow, { gap: spacing.xl, marginBottom: spacing.md }]}>
            <View style={styles.metaItem}>
              <Ionicons name="trending-up" size={16} color={colors.primary[500]} />
              <Text style={[styles.metaValue, { fontSize: fontSize.body }]}>{job.completion_percentage}%</Text>
            </View>
            {job.scheduled_start && (
              <View style={styles.metaItem}>
                <Ionicons name="calendar-outline" size={16} color={colors.gray[500]} />
                <Text style={[styles.metaValue, { fontSize: fontSize.body }]}>{new Date(job.scheduled_start).toLocaleDateString()}</Text>
              </View>
            )}
          </View>
          <View style={styles.progressContainer}>
            <View style={styles.progressBar}>
              <View style={[styles.progressFill, { width: `${job.completion_percentage}%` }]} />
            </View>
          </View>
        </AnimatedCard>

        {/* Status Actions */}
        {hasPermission('job.update') && statusActions[job.status] && (
          <AnimatedCard delay={100} style={{ marginTop: spacing.md }}>
            <Text style={[styles.sectionTitle, { fontSize: fontSize.body, marginBottom: spacing.md }]}>Actions</Text>
            <View style={[styles.actionGrid, { gap: spacing.sm }]}>
              {statusActions[job.status].map((status) => (
                <TouchableOpacity key={status} style={styles.statusButton} onPress={() => handleStatusChange(status)} activeOpacity={0.7}>
                  <Text style={[styles.statusButtonText, { fontSize: fontSize.bodySmall }]}>{status.replace(/_/g, ' ')}</Text>
                </TouchableOpacity>
              ))}
            </View>
          </AnimatedCard>
        )}

        {/* Checkin/Checkout + Photo */}
        {hasPermission('job.update') && (
          <AnimatedCard delay={200} style={{ marginTop: spacing.md }}>
            {isCheckedIn ? (
              <>
                <View style={styles.checkinInfo}>
                  <View style={[styles.checkinIconDone, { backgroundColor: colors.success[50] }]}>
                    <Ionicons name="checkmark-circle" size={24} color={colors.success[600]} />
                  </View>
                  <View style={{ flex: 1 }}>
                    <Text style={[styles.sectionTitle, { fontSize: fontSize.body }]}>Checked In</Text>
                    {checkinLocation ? (
                      <Text style={{ color: colors.gray[500], fontSize: fontSize.caption }} numberOfLines={1}>{checkinLocation}</Text>
                    ) : null}
                  </View>
                </View>

                <Text style={[styles.sectionTitle, { fontSize: fontSize.caption, marginTop: spacing.md, marginBottom: spacing.sm, color: colors.gray[500] }]}>PHOTOS</Text>
                <View style={styles.photoButtons}>
                  <TouchableOpacity style={styles.photoBtn} onPress={() => handleTakePhoto('BEFORE')} disabled={uploadingPhoto}>
                    <Ionicons name="camera-outline" size={20} color={colors.primary[600]} />
                    <Text style={[styles.photoBtnText, { fontSize: fontSize.caption }]}>Before</Text>
                  </TouchableOpacity>
                  <TouchableOpacity style={styles.photoBtn} onPress={() => handleTakePhoto('DURING')} disabled={uploadingPhoto}>
                    <Ionicons name="camera-outline" size={20} color={colors.warning[600]} />
                    <Text style={[styles.photoBtnText, { fontSize: fontSize.caption }]}>During</Text>
                  </TouchableOpacity>
                  <TouchableOpacity style={styles.photoBtn} onPress={() => handleTakePhoto('AFTER')} disabled={uploadingPhoto}>
                    <Ionicons name="camera-outline" size={20} color={colors.success[600]} />
                    <Text style={[styles.photoBtnText, { fontSize: fontSize.caption }]}>After</Text>
                  </TouchableOpacity>
                </View>

                {jobMedia.length > 0 && (
                  <View style={styles.photoGrid}>
                    {jobMedia.slice(0, 6).map((m) => {
                      const thumbStyle = { fontSize: 9, color: colors.gray[500] };
                      return (
                        <View key={m.id} style={styles.photoThumb}>
                          <Image
                            source={{ uri: getMediaUrl(m.file_url) }}
                            style={{ width: '100%', height: 60, borderRadius: radii.sm, backgroundColor: colors.gray[100] }}
                            resizeMode="cover"
                          />
                          <Text style={thumbStyle}>{m.media_type}</Text>
                        </View>
                      );
                    })}
                  </View>
                )}

                {uploadingPhoto && (
                  <View style={{ flexDirection: 'row', alignItems: 'center', gap: spacing.sm, paddingVertical: spacing.sm }}>
                    <ActivityIndicator size="small" color={colors.primary[500]} />
                    <Text style={{ color: colors.gray[500], fontSize: fontSize.caption }}>Uploading photo...</Text>
                  </View>
                )}

                <TouchableOpacity style={styles.checkoutButton} onPress={handleCheckOut} disabled={checkingOut} activeOpacity={0.7}>
                  {checkingOut ? (
                    <ActivityIndicator size="small" color={colors.white} />
                  ) : (
                    <Ionicons name="log-out-outline" size={20} color={colors.white} />
                  )}
                  <Text style={[styles.checkinButtonText, { fontSize: fontSize.body }]}>{checkingOut ? 'Checking out...' : 'Check Out'}</Text>
                </TouchableOpacity>
              </>
            ) : (
              <View style={styles.checkinPending}>
                <View style={[styles.checkinIconPending, { backgroundColor: colors.primary[50] }]}>
                  <Ionicons name="navigate" size={24} color={colors.primary[600]} />
                </View>
                <View style={{ flex: 1 }}>
                  <Text style={[styles.sectionTitle, { fontSize: fontSize.body }]}>Check-in</Text>
                  <Text style={{ color: colors.gray[500], fontSize: fontSize.caption }}>
                    {locationLoading ? 'Waiting for location...' : currentLocation ? 'Location ready' : 'Location not available'}
                  </Text>
                  {geofenceResult && !locationLoading && (
                    <Text style={{ color: geofenceResult.inside ? colors.success[600] : colors.warning[600], fontSize: fontSize.caption, marginTop: 2 }}>
                      {geofenceResult.inside ? 'Inside geofence' : 'Outside geofence'}
                      {geofenceResult.name ? ` (${geofenceResult.name})` : ''}
                      {geofenceResult.distance_meters != null ? ` - ${Math.round(geofenceResult.distance_meters)}m` : ''}
                    </Text>
                  )}
                </View>
                {locationLoading ? (
                  <ActivityIndicator size="small" color={colors.primary[500]} />
                ) : (
                  <TouchableOpacity onPress={refreshLocation} disabled={refreshingLocation} style={{ padding: spacing.xs }} activeOpacity={0.6}>
                    <Ionicons name={refreshingLocation ? 'refresh' : 'refresh-outline'} size={18} color={colors.primary[600]} />
                  </TouchableOpacity>
                )}
              </View>
            )}
          </AnimatedCard>
        )}

        {/* Assigned */}
        <AnimatedCard delay={300} style={{ marginTop: spacing.md }}>
          <View style={[styles.sectionHeader, { marginBottom: spacing.md }]}>
            <Text style={[styles.sectionTitle, { fontSize: fontSize.body }]}>Assigned ({assignments.length})</Text>
            {hasPermission('job.assign') && (
              <TouchableOpacity onPress={openAssignModal} style={styles.assignBtn}>
                <Ionicons name="person-add-outline" size={16} color={colors.primary[600]} />
                <Text style={[styles.assignBtnText, { fontSize: fontSize.bodySmall }]}>Assign</Text>
              </TouchableOpacity>
            )}
          </View>
          {assignments.length > 0 ? (
            assignments.map((a) => (
              <View key={a.user_id} style={[styles.assignmentRow, { paddingVertical: 10, gap: spacing.md, borderBottomWidth: 1, borderBottomColor: colors.gray[100] }]}>
                <View style={[styles.assignmentAvatar, { backgroundColor: colors.primary[100] }]}>
                  <Text style={[styles.assignmentAvatarText, { color: colors.primary[700], fontSize: fontSize.bodySmall }]}>
                    {a.first_name?.[0]}{a.last_name?.[0] || ''}
                  </Text>
                </View>
                <View style={styles.assignmentInfo}>
                  <Text style={[styles.assignmentName, { fontSize: fontSize.body }]}>{a.first_name} {a.last_name}</Text>
                  <Text style={[styles.assignmentRole, { fontSize: fontSize.caption }]}>{a.assignment_role}</Text>
                </View>
                <StatusBadge status={a.status} />
                {hasPermission('job.unassign') && (
                  <TouchableOpacity style={[styles.materialActionBtn, { backgroundColor: colors.danger?.[50] || '#fef2f2' }]} onPress={() => setDeleteMemberTarget(a)}>
                    <Ionicons name="trash-outline" size={14} color={colors.danger?.[600] || 'red'} />
                  </TouchableOpacity>
                )}
              </View>
            ))
          ) : (
            <Text style={[styles.emptyText, { fontSize: fontSize.body, paddingVertical: spacing.lg }]}>No assignments</Text>
          )}
        </AnimatedCard>

        {/* Notes */}
        <AnimatedCard delay={400} style={{ marginTop: spacing.md }}>
          <Text style={[styles.sectionTitle, { fontSize: fontSize.body, marginBottom: spacing.md }]}>Notes ({notes.length})</Text>
          {notes.map((note) => (
            <View key={note.id} style={[styles.noteItem, { paddingVertical: spacing.md, borderBottomWidth: 1, borderBottomColor: colors.gray[100] }]}>
              <View style={styles.noteHeader}>
                <Text style={[styles.noteAuthor, { fontSize: fontSize.bodySmall }]}>{note.first_name} {note.last_name}</Text>
                {note.created_at && <Text style={[styles.noteTime, { fontSize: fontSize.caption }]}>{new Date(note.created_at).toLocaleDateString()}</Text>}
              </View>
              <Text style={[styles.noteText, { fontSize: fontSize.body, lineHeight: 20 }]}>{note.note}</Text>
            </View>
          ))}
          {hasPermission('job.update') && (
            <View style={[styles.noteInput, { flexDirection: isPhone ? 'column' : 'row', alignItems: isPhone ? 'stretch' : 'flex-end', gap: spacing.sm, marginTop: spacing.md }]}>
              <TextInput
                style={[styles.noteTextInput, { flex: isPhone ? undefined : 1, paddingHorizontal: spacing.md, paddingVertical: 10, fontSize: fontSize.body, maxHeight: 80 }]}
                placeholder="Add a note..."
                placeholderTextColor={colors.gray[400]}
                value={newNote}
                onChangeText={setNewNote}
                multiline
              />
              <TouchableOpacity
                style={[styles.noteSend, (!newNote.trim() || submittingNote) && styles.noteSendDisabled, isPhone && { width: '100%', height: 44, justifyContent: 'center' }]}
                onPress={handleAddNote}
                disabled={!newNote.trim() || submittingNote}
                activeOpacity={0.7}
              >
                <Ionicons name="send" size={16} color={colors.white} />
              </TouchableOpacity>
            </View>
          )}
        </AnimatedCard>

        {/* Materials */}
        <AnimatedCard delay={500} style={{ marginTop: spacing.md }}>
          <View style={[styles.sectionHeader, { marginBottom: spacing.md }]}>
            <Text style={[styles.sectionTitle, { fontSize: fontSize.body }]}>Materials ({jobMaterials.length})</Text>
            {hasPermission('material.request') && (
              <TouchableOpacity onPress={() => { loadMaterials(); setShowMaterialModal(true); }} style={styles.assignBtn}>
                <Ionicons name="add-circle-outline" size={16} color={colors.primary[600]} />
                <Text style={[styles.assignBtnText, { fontSize: fontSize.bodySmall }]}>Request</Text>
              </TouchableOpacity>
            )}
          </View>
          {jobMaterials.length > 0 ? (
            jobMaterials.map((mat) => {
              const isAssigned = mat.material_status === 'IN_USE';
              const isReturned = mat.material_status === 'RETURNED';
              const isStock = mat.material_status === 'STOCK' || !mat.material_status;
              const personName = mat.assigned_to_name ? `${mat.assigned_to_name} ${mat.assigned_to_last || ''}` : null;
              return (
                <View key={mat.id} style={[styles.materialRow, { paddingVertical: spacing.sm, gap: spacing.md, borderBottomWidth: 1, borderBottomColor: colors.gray[100] }]}>
                  <View style={[styles.materialIcon, { backgroundColor: isReturned ? colors.success[50] : isAssigned ? colors.warning[50] : colors.primary[50] }]}>
                    <Ionicons name={isReturned ? 'checkmark-circle-outline' : isAssigned ? 'person-outline' : 'cube-outline'} size={18} color={isReturned ? colors.success[600] : isAssigned ? colors.warning[600] : colors.primary[600]} />
                  </View>
                  <View style={styles.materialInfo}>
                    <Text style={[styles.materialName, { fontSize: fontSize.body }]} numberOfLines={1}>{mat.material_name}</Text>
                    <View style={styles.materialMeta}>
                      <StatusBadge status={mat.material_status || 'STOCK'} />
                      {mat.approved_quantity > 0 && <Text style={[styles.materialQty, { color: colors.gray[500], fontSize: fontSize.caption }]}>x{mat.approved_quantity}</Text>}
                    </View>
                    {personName && (
                      <View style={styles.materialPerson}>
                        <Ionicons name="person-outline" size={11} color={colors.warning[500]} />
                        <Text style={[styles.materialPersonText, { color: colors.warning[700], fontSize: fontSize.caption }]}>{personName}</Text>
                      </View>
                    )}
                  </View>
                  <View style={styles.materialActions}>
                    {isStock && mat.status === 'REQUESTED' && hasPermission('material.approve') && (
                      <TouchableOpacity style={[styles.materialActionBtn, { backgroundColor: colors.primary[50] }]} onPress={() => openAssignMaterial(mat)}>
                        <Ionicons name="person-add-outline" size={14} color={colors.primary[600]} />
                      </TouchableOpacity>
                    )}
                    {isAssigned && (
                      <TouchableOpacity style={[styles.materialActionBtn, { backgroundColor: colors.success[50] }]} onPress={() => setReturnTarget(mat)}>
                        <Ionicons name="return-down-back-outline" size={14} color={colors.success[600]} />
                      </TouchableOpacity>
                    )}
                    {hasPermission('job.update') && (
                      <TouchableOpacity style={[styles.materialActionBtn, { backgroundColor: colors.danger?.[50] || '#fef2f2' }]} onPress={() => setDeleteMaterialTarget(mat)}>
                        <Ionicons name="trash-outline" size={14} color={colors.danger?.[600] || 'red'} />
                      </TouchableOpacity>
                    )}
                  </View>
                </View>
              );
            })
          ) : (
            <Text style={[styles.emptyText, { fontSize: fontSize.body, paddingVertical: spacing.lg }]}>No materials requested</Text>
          )}
        </AnimatedCard>

        <View style={{ height: 40 }} />
      </ScreenContainer>

      {/* Modals */}
      <Modal visible={showAssignModal} animationType="slide" transparent>
        <View style={styles.modalOverlay}>
          <View style={styles.modalContent}>
            <View style={styles.modalHeader}>
              <Text style={[styles.modalTitle, { fontSize: fontSize.h3 }]}>Assign User</Text>
              <TouchableOpacity onPress={() => setShowAssignModal(false)}><Ionicons name="close" size={24} color={colors.gray[600]} /></TouchableOpacity>
            </View>
            {availableUsers.length > 0 ? (
              <FlatList data={availableUsers} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => (
                <TouchableOpacity style={[styles.userOption, { paddingVertical: 12, paddingHorizontal: spacing.lg }]} onPress={() => handleAssign(item.id)} disabled={assigning}>
                  <View style={[styles.userAvatar, { backgroundColor: colors.primary[100] }]}><Text style={[styles.userAvatarText, { color: colors.primary[700] }]}>{item.first_name[0]}{item.last_name?.[0] || ''}</Text></View>
                  <View style={styles.userInfo}><Text style={[styles.userName, { fontSize: fontSize.body }]}>{item.first_name} {item.last_name}</Text><Text style={[styles.userEmail, { fontSize: fontSize.caption }]}>{item.email}</Text></View>
                  <Ionicons name="add-circle-outline" size={22} color={colors.primary[600]} />
                </TouchableOpacity>
              )} />
            ) : (
              <Text style={[styles.emptyText, { padding: spacing.xl }]}>All users are already assigned</Text>
            )}
          </View>
        </View>
      </Modal>

      <Modal visible={showMaterialModal} animationType="slide" transparent>
        <View style={styles.modalOverlay}>
          <View style={styles.modalContent}>
            <View style={styles.modalHeader}>
              <Text style={[styles.modalTitle, { fontSize: fontSize.h3 }]}>Request Material</Text>
              <TouchableOpacity onPress={() => { setShowMaterialModal(false); setSelectedMaterialId(null); }}><Ionicons name="close" size={24} color={colors.gray[600]} /></TouchableOpacity>
            </View>
            <View style={{ padding: spacing.lg, gap: spacing.md }}>
              <View>
                <Text style={[styles.fieldLabel, { fontSize: fontSize.caption }]}>Material * (Stock items only)</Text>
                <View style={styles.pickerContainer}>
                  {availableMaterials.filter(m => (m.stock_quantity || 0) > 0).map((m) => (
                    <TouchableOpacity key={m.id} style={[styles.pickerItem, selectedMaterialId === m.id && styles.pickerItemActive]} onPress={() => setSelectedMaterialId(m.id)}>
                      <Text style={[styles.pickerText, { color: selectedMaterialId === m.id ? colors.white : colors.gray[700], fontSize: fontSize.body }]}>{m.material_name}</Text>
                      <Text style={{ color: selectedMaterialId === m.id ? colors.white : colors.gray[500], fontSize: fontSize.caption }}>Stock: {m.stock_quantity}</Text>
                    </TouchableOpacity>
                  ))}
                  {availableMaterials.filter(m => (m.stock_quantity || 0) > 0).length === 0 && <Text style={{ color: colors.gray[500], fontSize: fontSize.body, padding: spacing.md }}>No materials in stock</Text>}
                </View>
              </View>
              <View>
                <Text style={[styles.fieldLabel, { fontSize: fontSize.caption }]}>Quantity *</Text>
                <TextInput style={[styles.modalInput, { fontSize: fontSize.body }]} placeholder="1" placeholderTextColor={colors.gray[400]} value={materialQuantity} onChangeText={setMaterialQuantity} keyboardType="numeric" />
              </View>
              <View>
                <Text style={[styles.fieldLabel, { fontSize: fontSize.caption }]}>Remarks</Text>
                <TextInput style={[styles.modalInput, { fontSize: fontSize.body }]} placeholder="Optional remarks" placeholderTextColor={colors.gray[400]} value={materialRemarks} onChangeText={setMaterialRemarks} />
              </View>
              <TouchableOpacity style={[styles.createButton, (!selectedMaterialId || requestingMaterial) && { opacity: 0.5 }]} onPress={handleRequestMaterial} disabled={!selectedMaterialId || requestingMaterial}>
                <Text style={[styles.createButtonText, { fontSize: fontSize.body }]}>{requestingMaterial ? 'Requesting...' : 'Request Material'}</Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>

      <Modal visible={showAssignMaterialModal} animationType="slide" transparent>
        <View style={styles.modalOverlay}>
          <View style={styles.modalContent}>
            <View style={styles.modalHeader}>
              <Text style={[styles.modalTitle, { fontSize: fontSize.h3 }]}>Assign to Person</Text>
              <TouchableOpacity onPress={() => { setShowAssignMaterialModal(false); setAssignTarget(null); }}><Ionicons name="close" size={24} color={colors.gray[600]} /></TouchableOpacity>
            </View>
            <Text style={{ padding: spacing.lg, paddingBottom: 0, color: colors.gray[600], fontSize: fontSize.caption }}>{assignTarget?.material_name}</Text>
            {assignments.length > 0 ? (
              <FlatList data={assignments} keyExtractor={(item) => item.user_id.toString()} renderItem={({ item }) => (
                <TouchableOpacity style={[styles.userOption, { paddingVertical: 12, paddingHorizontal: spacing.lg }]} onPress={() => handleAssignMaterial(item.user_id)} disabled={assigningMaterial}>
                  <View style={[styles.userAvatar, { backgroundColor: colors.primary[100] }]}><Text style={[styles.userAvatarText, { color: colors.primary[700] }]}>{item.first_name?.[0]}{item.last_name?.[0] || ''}</Text></View>
                  <View style={styles.userInfo}><Text style={[styles.userName, { fontSize: fontSize.body }]}>{item.first_name} {item.last_name}</Text><Text style={[styles.userEmail, { fontSize: fontSize.caption }]}>{item.assignment_role}</Text></View>
                  <Ionicons name="add-circle-outline" size={22} color={colors.primary[600]} />
                </TouchableOpacity>
              )} />
            ) : (
              <Text style={[styles.emptyText, { padding: spacing.xl }]}>No users assigned to this job</Text>
            )}
          </View>
        </View>
      </Modal>

      <ConfirmDialog visible={!!returnTarget} title="Return to Stock" message={`Return "${returnTarget?.material_name}" to stock?`} confirmLabel="Return" cancelLabel="Cancel" onConfirm={handleReturnMaterial} onCancel={() => setReturnTarget(null)} />
      <ConfirmDialog visible={deleteJobTarget} title="Delete Job" message={`Are you sure you want to delete "${job?.title}"? This cannot be undone.`} confirmLabel={deletingJob ? 'Deleting...' : 'Delete'} cancelLabel="Cancel" onConfirm={handleDeleteJob} onCancel={() => setDeleteJobTarget(false)} />
      <ConfirmDialog visible={!!deleteMemberTarget} title="Remove Member" message={`Remove "${deleteMemberTarget?.first_name} ${deleteMemberTarget?.last_name}" from this job?`} confirmLabel={deletingMember ? 'Removing...' : 'Remove'} cancelLabel="Cancel" onConfirm={handleRemoveMember} onCancel={() => setDeleteMemberTarget(null)} />
      <ConfirmDialog visible={!!deleteMaterialTarget} title="Remove Material" message={`Remove "${deleteMaterialTarget?.material_name}" from this job?${deleteMaterialTarget?.material_status === 'IN_USE' ? ' Stock will be returned.' : ''}`} confirmLabel={deletingMaterial ? 'Removing...' : 'Remove'} cancelLabel="Cancel" onConfirm={handleRemoveMaterial} onCancel={() => setDeleteMaterialTarget(null)} />
    </>
  );
}

const styles = StyleSheet.create({
  locationHeader: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm, marginBottom: spacing.md },
  locationIconWrap: { width: 32, height: 32, borderRadius: radii.md, justifyContent: 'center', alignItems: 'center' },
  addressText: { color: colors.gray[600], lineHeight: 18 },
  headerRow: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm, marginBottom: spacing.md },
  checkedInBadge: { flexDirection: 'row', alignItems: 'center', gap: 4, paddingHorizontal: 8, paddingVertical: 3, borderRadius: radii.full },
  description: { color: colors.gray[600] },
  metaRow: { flexDirection: 'row' },
  metaItem: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs },
  metaValue: { fontWeight: '500', color: colors.gray[700] },
  progressContainer: {},
  progressBar: { height: 6, backgroundColor: colors.gray[100], borderRadius: 3, overflow: 'hidden' },
  progressFill: { height: '100%', backgroundColor: colors.primary[500], borderRadius: 3 },
  sectionTitle: { fontWeight: '600', color: colors.gray[900] },
  sectionHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  actionGrid: { flexDirection: 'row', flexWrap: 'wrap' },
  statusButton: { backgroundColor: colors.primary[50], borderWidth: 1, borderColor: colors.primary[200], paddingHorizontal: spacing.lg, paddingVertical: 10, borderRadius: radii.md },
  statusButtonText: { color: colors.primary[700], fontWeight: '600', textTransform: 'capitalize' },
  checkinInfo: { flexDirection: 'row', alignItems: 'center', gap: spacing.md },
  checkinIconDone: { width: 40, height: 40, borderRadius: radii.lg, justifyContent: 'center', alignItems: 'center' },
  checkinPending: { flexDirection: 'row', alignItems: 'center', gap: spacing.md },
  checkinIconPending: { width: 40, height: 40, borderRadius: radii.lg, justifyContent: 'center', alignItems: 'center' },
  checkoutButton: { backgroundColor: colors.danger[600], flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: spacing.sm, paddingVertical: 14, borderRadius: radii.md, marginTop: spacing.md },
  checkinButtonText: { color: colors.white, fontWeight: '600' },
  photoButtons: { flexDirection: 'row', gap: spacing.sm },
  photoBtn: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: spacing.xs, paddingVertical: 12, borderRadius: radii.md, borderWidth: 1, borderColor: colors.gray[200], backgroundColor: colors.white },
  photoBtnText: { fontWeight: '600', color: colors.gray[700] },
  photoGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: spacing.xs, marginTop: spacing.md },
  photoThumb: { width: 80, gap: 2, borderRadius: radii.md, backgroundColor: colors.gray[100], overflow: 'hidden' },
  assignBtn: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs, paddingHorizontal: spacing.md, paddingVertical: spacing.sm, backgroundColor: colors.primary[50], borderRadius: radii.md },
  assignBtnText: { color: colors.primary[600], fontWeight: '600' },
  assignmentRow: { flexDirection: 'row', alignItems: 'center' },
  assignmentAvatar: { width: 34, height: 34, borderRadius: radii.full, justifyContent: 'center', alignItems: 'center' },
  assignmentAvatarText: { fontWeight: '700' },
  assignmentInfo: { flex: 1 },
  assignmentName: { fontWeight: '600', color: colors.gray[900] },
  assignmentRole: { color: colors.gray[500] },
  emptyText: { color: colors.gray[400], textAlign: 'center' },
  noteItem: {},
  noteHeader: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 4 },
  noteAuthor: { fontWeight: '600', color: colors.gray[800] },
  noteTime: { color: colors.gray[400] },
  noteText: { color: colors.gray[600] },
  noteInput: {},
  noteTextInput: { backgroundColor: colors.gray[50], borderRadius: radii.md, borderWidth: 1, borderColor: colors.gray[200], color: colors.gray[900] },
  noteSend: { width: 40, height: 40, borderRadius: radii.md, backgroundColor: colors.primary[600], justifyContent: 'center', alignItems: 'center' },
  noteSendDisabled: { opacity: 0.5 },
  materialRow: { flexDirection: 'row', alignItems: 'center' },
  materialIcon: { width: 34, height: 34, borderRadius: radii.md, justifyContent: 'center', alignItems: 'center' },
  materialInfo: { flex: 1, gap: 2 },
  materialName: { fontWeight: '600', color: colors.gray[900] },
  materialMeta: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs },
  materialQty: { fontWeight: '500' },
  materialPerson: { flexDirection: 'row', alignItems: 'center', gap: 3 },
  materialPersonText: { fontWeight: '500' },
  materialActions: { flexDirection: 'row', gap: spacing.xs },
  materialActionBtn: { width: 30, height: 30, borderRadius: radii.sm, justifyContent: 'center', alignItems: 'center' },
  fieldLabel: { fontWeight: '600', color: colors.gray[700], marginBottom: spacing.xs },
  pickerContainer: { gap: spacing.xs },
  pickerItem: { paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderRadius: radii.md, borderWidth: 1, borderColor: colors.gray[200], backgroundColor: colors.white, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  pickerItemActive: { backgroundColor: colors.primary[600], borderColor: colors.primary[600] },
  pickerText: { fontWeight: '500' },
  modalOverlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'flex-end' },
  modalContent: { backgroundColor: colors.white, borderTopLeftRadius: radii.xl, borderTopRightRadius: radii.xl, maxHeight: '70%' },
  modalHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: spacing.lg, borderBottomWidth: 1, borderBottomColor: colors.border },
  modalTitle: { fontWeight: '700', color: colors.gray[900] },
  modalInput: { backgroundColor: colors.gray[50], borderRadius: radii.md, paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderWidth: 1, borderColor: colors.gray[200], color: colors.gray[900] },
  createButton: { backgroundColor: colors.primary[600], borderRadius: radii.md, paddingVertical: spacing.md, alignItems: 'center' },
  createButtonText: { color: colors.white, fontWeight: '600' },
  userOption: { flexDirection: 'row', alignItems: 'center', gap: spacing.md, borderBottomWidth: 1, borderBottomColor: colors.gray[100] },
  userAvatar: { width: 40, height: 40, borderRadius: 20, justifyContent: 'center', alignItems: 'center' },
  userAvatarText: { fontWeight: '700', fontSize: 14 },
  userInfo: { flex: 1 },
  userName: { fontWeight: '600', color: colors.gray[900] },
  userEmail: { color: colors.gray[500] },
});
