export type UserRole = 'Super_admin' | 'Admin' | 'User';

export interface Designation {
  id: number;
  name: string;
  order_id: number;
  department_id?: number;
  parent_id?: number | null;
  description?: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
  department_name?: string;
  parent_name?: string;
}

export interface User {
  id: number;
  name: string;
  order_id: number;
  time?: string;
  organization_id: number;
  organization?: string;
  rank: string;
  service_no: string;
  unit: string;
  branch: string;
  subBranch?: string;
  department?: string;
  role: UserRole; // Access role (Super_admin, Admin, User)
  designation: string; // Position designation (CNS, Secy to CNS, Asst. Secy, Flag Lt, etc.)
  designation_id?: number; // Designation ID for API compatibility
  phone: string; // Telephone/landline number
  mobile?: string; // Primary mobile/cell phone number
  alternative_mobile?: string; // Alternative mobile/cell phone number
  email: string;
  occupation?: string;
  facebook?: string;
  linkedin?: string;
  present_address?: string;
  present_lat_lng?: string;
  office_address?: string;
  office_lat_lng?: string;
  permanent_address?: string;
  permanent_lat_lng?: string;
  avatar?: string;
  logo?: string;
  status: 'online' | 'offline' | 'busy';
  lastSeen?: Date;
  // Additional fields for Contact API compatibility
  parent_id?: number | null;
  contact_type?: 'internal' | 'external';
  children?: User[];
}

export interface Message {
  id: number;
  senderId: number;
  receiverId?: number;
  groupId?: number;
  content: string;
  timestamp: Date;
  type: 'text' | 'system' | 'file' | 'image';
  read: boolean;
}

export interface ConversationParticipant {
  id: number;
  conversation_id: number;
  user_id: number;
  user_name: string;
  user_avatar: string | null;
  user_rank: string;
  user_designation: string;
  joined_at: string;
  last_read_at: string | null;
  role: 'admin' | 'member';
  is_active: boolean;
}

export interface Conversation {
  id: number;
  type: 'direct' | 'group';
  name?: string;
  participants: ConversationParticipant[];
  lastMessage?: Message;
  unreadCount: number;
}

export interface AuditLog {
  id: number;
  userId: number;
  action: string;
  target?: string;
  timestamp: Date;
  details: string;
}

export interface AuthUser {
  id: number;
  name: string;
  organization_id?: number;
  rank_id: number;
  service_no: string;
  unit_id: number;
  department_id: number;
  role_id: number;
  role: string; // Access role (Super_admin, Admin, User) - using string to match API
  designation_id: number;
  parent_id: number | null;
  phone: string;
  mobile: string;
  alternative_mobile: string | null;
  email: string;
  avatar: string | null;
  status: string;
  last_seen: string;
  is_active: number;
  created_at: string;
  updated_at: string;
  permissions: string[];
}

// API Response types
export interface ApiResponse<T> {
  status: 'success' | 'error';
  message: string;
  data?: T;
  error?: string;
}

export interface LoginRequest {
  email: string;
  password: string;
}

export interface LoginResponse {
  user: {
    id: number;
    name: string;
    rank_id: number;
    service_no: string;
    unit_id: number;
    department_id: number;
    role_id: number;
    role: string;
    designation_id: number;
    parent_id: number | null;
    phone: string;
    mobile: string;
    alternative_mobile: string | null;
    email: string;
    avatar: string | null;
    status: string;
    last_seen: string;
    is_active: number;
    created_at: string;
    updated_at: string;
    permissions: string[];
  };
  token: string;
  refreshToken: string;
}

export interface FeedbackFormData {
  id?: number;
  name: string;
  email: string;
  phone: string;
  rating: number;
  category: string;
  subject: string;
  message: string;
  satisfaction: string;
  recommend: string;
  improvements: string[];
  anonymous: boolean;
  timestamp?: Date;
  status?: 'pending' | 'reviewed' | 'resolved';
}

// Role-based access control utilities
export const USER_ROLES = {
  SUPER_ADMIN: 'Super_admin' as const,
  ADMIN: 'Admin' as const,
  USER: 'User' as const,
} as const;

export const ROLE_HIERARCHY = {
  [USER_ROLES.SUPER_ADMIN]: 3,
  [USER_ROLES.ADMIN]: 2,
  [USER_ROLES.USER]: 1,
} as const;

// Utility functions for role management
export const hasRole = (userRole: UserRole, requiredRole: UserRole): boolean => {
  return ROLE_HIERARCHY[userRole] >= ROLE_HIERARCHY[requiredRole];
};

export const isSuperAdmin = (role: UserRole): boolean => role === USER_ROLES.SUPER_ADMIN;
export const isAdmin = (role: UserRole): boolean => role === USER_ROLES.ADMIN || role === USER_ROLES.SUPER_ADMIN;
export const isUser = (role: UserRole): boolean => role === USER_ROLES.USER;

// Permission checking utilities
export const hasPermission = (user: AuthUser, permission: string): boolean => {
  return user.permissions.includes(permission);
};

export const hasAnyPermission = (user: AuthUser, permissions: string[]): boolean => {
  return permissions.some(permission => user.permissions.includes(permission));
};

export const hasAllPermissions = (user: AuthUser, permissions: string[]): boolean => {
  return permissions.every(permission => user.permissions.includes(permission));
};

// Contact API Types
export interface Contact {
  id: number;
  order_id: number | null;
  name: string;
  rank_id: number | null;
  rank_name: string | null;
  service_no: string | null;
  unit_id: number;
  unit_name: string;
  branch_id: number | null;
  branch_name: string | null;
  sub_branch_id: number | null;
  sub_branch_name: string | null;
  department_id: number | null;
  department_name: string | null;
  designation_id: number | null;
  designation_name: string | null;
  organization: string | null;
  phone: string;
  mobile: string | null;
  alternative_mobile: string | null;
  email: string;
  occupation: string | null;
  facebook: string | null;
  linkedin: string | null;
  parent_id: number | null;
  contact_type: 'internal' | 'external';
  is_active: boolean;
  created_by: number;
  created_by_name: string;
  created_at: string;
  updated_at: string;
  role_id: number;
  logo: string | null;
  avatar: string | null;
  status: 'online' | 'offline' | 'busy';
  last_seen: string | null;
  children?: Contact[];
}

export interface ContactStatistics {
  total_contacts: number;
  internal_contacts: number;
  external_contacts: number;
  root_contacts: number;
  child_contacts: number;
}

export interface ContactPagination {
  page: number;
  limit: number;
  total: number;
}

export interface ContactListResponse {
  contacts: Contact[];
  statistics: ContactStatistics;
  pagination: ContactPagination;
}

export interface ContactResponse {
  contact: Contact;
}

export interface ContactChildrenResponse {
  parent: Contact;
  children: Contact[];
}

export interface ContactSearchResponse {
  contacts: Contact[];
  searchTerm: string;
  total: number;
}

export interface ContactCreateRequest {
  name: string;
  rank_id?: number;
  service_no?: string;
  order_id?: number;
  unit_id?: number;
  branch_id?: number;
  sub_branch_id?: number;
  department_id?: number;
  designation_id?: number;
  designation?: string;
  organization?: string;
  phone?: string;
  mobile?: string;
  alternative_mobile?: string;
  email?: string;
  present_address?: string;
  present_lat_lng?: string;
  office_address?: string;
  office_lat_lng?: string;
  permanent_address?: string;
  permanent_lat_lng?: string;
  occupation?: string;
  facebook?: string;
  linkedin?: string;
  parent_id?: number;
}

export interface ContactUpdateRequest extends Partial<ContactCreateRequest> {}

export interface ContactMoveRequest {
  parent_id: number;
}

export interface BulkDeleteRequest {
  contactIds: number[];
}

export interface BulkDeleteResponse {
  deleted: Array<{ id: number; status: string }>;
  errors: Array<{ id: number; error: string }>;
  summary: {
    total: number;
    deleted: number;
    errors: number;
  };
}

// Utility functions to convert between Contact and User formats
export const contactToUser = (contact: Contact): User => ({
  id: contact.id,
  order_id: (contact.order_id ?? 0),
  name: contact.name,
  rank: contact.rank_name || '',
  service_no: contact.service_no || '',
  unit: contact.unit_name,
  branch: contact.branch_name || '',
  subBranch: contact.sub_branch_name || undefined,
  department: contact.department_name || undefined,
  role: contact.role_id === 1 ? 'Super_admin' : contact.role_id === 2 ? 'Admin' : 'User',
  designation: contact.designation_name || '',
  designation_id: contact.designation_id || undefined,
  organization: contact.organization || undefined,
  phone: contact.phone,
  mobile: contact.mobile || undefined,
  alternative_mobile: contact.alternative_mobile || undefined,
  email: contact.email,
  occupation: contact.occupation || undefined,
  facebook: contact.facebook || undefined,
  linkedin: contact.linkedin || undefined,
  present_address: contact.present_address || undefined,
  present_lat_lng: contact.present_lat_lng || undefined,
  office_address: contact.office_address || undefined,
  office_lat_lng: contact.office_lat_lng || undefined,
  permanent_address: contact.permanent_address || undefined,
  permanent_lat_lng: contact.permanent_lat_lng || undefined,
  avatar: contact.avatar || undefined,
  logo: contact.logo || contact.avatar || undefined,
  status: contact.status,
  lastSeen: contact.last_seen ? new Date(contact.last_seen) : undefined,
  parent_id: contact.parent_id,
  contact_type: contact.contact_type,
  children: contact.children?.map(contactToUser),
});

export const userToContact = (user: User): ContactCreateRequest => ({
  name: user.name,
  order_id: user.order_id,
  service_no: user.service_no,
  organization: user.organization,
  phone: user.phone,
  mobile: user.mobile,
  alternative_mobile: user.alternative_mobile,
  email: user.email,
  present_address: user.present_address,
  present_lat_lng: user.present_lat_lng,
  office_address: user.office_address,
  office_lat_lng: user.office_lat_lng,
  permanent_address: user.permanent_address,
  permanent_lat_lng: user.permanent_lat_lng,
  designation: user.designation,
  occupation: user.occupation,
  facebook: user.facebook,
  linkedin: user.linkedin,
  parent_id: user.parent_id || undefined,
});

// Unit API Types
export interface Unit {
  id: number;
  name: string;
  code: string;
  order_id: number;
  description: string;
  parent_id?: number | null;
  parent_name?: string | null;
  is_active: boolean;
  total_users: number;
  created_at: string;
  updated_at: string;
}

export interface UnitStatistics {
  total_units: number;
  units_with_users: number;
  total_users_in_units: number;
  total_users_without_unit: number;
}

export interface UnitPagination {
  page: number;
  limit: number;
  total: number;
}

export interface UnitFilters {
  search: string;
  include_inactive: boolean;
}

export interface UnitsListResponse {
  units: Unit[];
  statistics: UnitStatistics;
  pagination: UnitPagination;
  filters: UnitFilters;
}

// Department API Types
export interface Department {
  id: number;
  name: string;
  order_id: number;
  unit_id: number;
  unit_name: string;
  unit_code: string;
  description: string;
  logo?: string | null;
  parent_id?: number | null;
  parent_name?: string | null;
  is_active: number;
  total_users: number;
  created_at: string;
  updated_at: string;
}

export interface DepartmentStatistics {
  total_departments: number;
  units_with_departments: number;
  total_users_in_departments: number;
  total_users_without_department: number;
}

export interface DepartmentPagination {
  page: number;
  limit: number;
  total: number;
}

export interface DepartmentFilters {
  search: string;
  unit_id: string;
  include_inactive: boolean;
}

export interface DepartmentsListResponse {
  departments: Department[];
  statistics: DepartmentStatistics;
  pagination: DepartmentPagination;
  filters: DepartmentFilters;
}

// Messaging Types
export interface Message {
  id: number;
  conversation_id: number;
  sender_id: number;
  content: string;
  type: 'text' | 'system' | 'file' | 'image';
  is_read: boolean;
  created_at: string;
  updated_at: string;
  sender_name: string;
  sender_avatar: string | null;
  sender_rank: string;
  sender_designation: string;
  reply_to?: number;
  edited_at?: string;
  deleted_at?: string;
}

export interface Conversation {
  id: number;
  type: 'direct' | 'group';
  name?: string;
  description?: string;
  created_by: number;
  created_at: string;
  updated_at: string;
  last_message?: Message;
  participants: ConversationParticipant[];
  unread_count: number;
  is_archived: boolean;
  is_muted: boolean;
  avatar?: string;
}

export interface Notification {
  id: number;
  user_id: number;
  type: 'message' | 'conversation' | 'system' | 'info' | 'warning' | 'error';
  title: string;
  message: string;
  data?: any;
  is_read: boolean;
  created_at: string;
  read_at?: string;
  expires_at?: string;
}

export interface TypingUser {
  user_id: number;
  user_name: string;
  user_avatar: string | null;
  user_rank: string;
  isTyping: boolean;
  started_at: string;
}

export interface UserStatus {
  user_id: number;
  status: 'online' | 'offline' | 'busy' | 'away';
  last_seen: string;
}

// API Request/Response Types
export interface SendMessageRequest {
  conversation_id: number;
  content: string;
  type?: 'text' | 'system' | 'file' | 'image';
  reply_to?: number;
}

export interface SendMessageResponse {
  message: Message;
}

export interface GetMessagesRequest {
  conversation_id: number;
  page?: number;
  limit?: number;
  before_id?: number;
  after_id?: number;
}

export interface GetMessagesResponse {
  messages: Message[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    has_more: boolean;
  };
}

export interface CreateConversationRequest {
  type: 'direct' | 'group';
  name?: string;
  description?: string;
  participant_ids: number[];
}

export interface CreateConversationResponse {
  conversation: Conversation;
  participants: ConversationParticipant[];
}

export interface GetConversationsResponse {
  conversations: Conversation[];
  pagination: {
    page: number;
    limit: number;
    total: number;
  };
}

export interface GetNotificationsRequest {
  page?: number;
  limit?: number;
  type?: 'message' | 'conversation' | 'system' | 'info' | 'warning' | 'error';
  is_read?: boolean;
}

export interface GetNotificationsResponse {
  notifications: Notification[];
  pagination: {
    page: number;
    limit: number;
    total: number;
  };
}

export interface NotificationStatistics {
  total_notifications: number;
  unread_notifications: number;
  by_type: {
    message: number;
    conversation: number;
    system: number;
    info: number;
    warning: number;
    error: number;
  };
}

export interface SearchMessagesRequest {
  q: string;
  conversation_id?: number;
  page?: number;
  limit?: number;
}

export interface SearchMessagesResponse {
  messages: Message[];
  search_term: string;
  pagination: {
    page: number;
    limit: number;
    total: number;
  };
}

export interface UpdateMessageRequest {
  content: string;
}

export interface MarkMessagesReadRequest {
  conversation_id: number;
  message_ids?: number[];
}

export interface TypingIndicatorRequest {
  conversation_id: number;
  isTyping: boolean;
}

// Socket.IO Event Types
export interface SocketEvents {
  // Client to Server Events
  join_conversation: { conversationId: number };
  leave_conversation: { conversationId: number };
  typing_start: { conversationId: number };
  typing_stop: { conversationId: number };
  message_delivered: { messageId: number; conversationId: number };
  message_read: { messageId: number; conversationId: number };
  status_update: { status: 'online' | 'offline' | 'busy' | 'away' };
  
  // Server to Client Events
  new_message: { message: Message; conversation_id: number };
  message_updated: { message: Message };
  message_deleted: { message_id: number; conversation_id: number };
  messages_read: { user_id: number; conversation_id: number; read_at: string };
  user_typing: { user: { id: number; name: string; avatar: string | null; rank: string }; isTyping: boolean; conversation_id: number };
  user_status_changed: { user_id: number; status: 'online' | 'offline' | 'busy' | 'away' };
  conversation_created: { conversation: Conversation };
  participant_added: { conversation_id: number; user: ConversationParticipant };
  participant_removed: { conversation_id: number; user_id: number };
  conversation_updated: { conversation: Conversation };
  conversation_deleted: { conversation_id: number };
  new_notification: { notification: Notification };
  notification_read: { notification_id: number };
}

// Messaging State Types
export interface MessagingState {
  conversations: Conversation[];
  currentConversation: Conversation | null;
  messages: Message[];
  notifications: Notification[];
  typingUsers: TypingUser[];
  onlineUsers: UserStatus[];
  isLoading: boolean;
  error: string | null;
  unreadCount: number;
}

export interface MessagingContextType extends MessagingState {
  // Actions
  sendMessage: (conversationId: number, content: string, type?: 'text' | 'system' | 'file' | 'image', replyTo?: number) => Promise<void>;
  createConversation: (type: 'direct' | 'group', participantIds: number[], name?: string, description?: string) => Promise<Conversation>;
  getMessages: (conversationId: number, page?: number, limit?: number) => Promise<void>;
  markMessagesAsRead: (conversationId: number, messageIds?: number[]) => Promise<void>;
  searchMessages: (query: string, conversationId?: number) => Promise<Message[]>;
  updateMessage: (messageId: number, content: string) => Promise<void>;
  deleteMessage: (messageId: number) => Promise<void>;
  setTyping: (conversationId: number, isTyping: boolean) => void;
  setCurrentConversation: (conversation: Conversation | null) => void;
  refreshConversations: () => Promise<void>;
  getNotifications: (page?: number, limit?: number, type?: string, isRead?: boolean) => Promise<void>;
  markNotificationAsRead: (notificationId: number) => Promise<void>;
  markAllNotificationsAsRead: () => Promise<void>;
  deleteNotification: (notificationId: number) => Promise<void>;
  getNotificationStatistics: () => Promise<NotificationStatistics>;
}

// Common designations
export const DESIGNATIONS = [
  'CNS',
  'Secy to CNS',
  'Asst. Secy',
  'Flag Lt',
  'Protocol Offr',
  'Escort Offr',
  'NS',
  'SONA-1',
  'SONA-1 (Tec)',
  'SONA-2',
  'SONA-2 (Plans)',
  'SO Tec',
  'DA',
  'DD Drafting',
  'Sec Comd-1',
  'Sec Comd-2',
  'Sec Comd-3',
  'JAG',
  'DD JAG',
  'SO (JAG)',
  'ACNS (O)',
  'Coord to ACNS(O)',
  'DNO',
  'DDNO',
  'SO(O)',
  'SO (Ops Plan)',
  'Area Commander',
  'Deputy Commander',
  'Staff Officer',
] as const;
