import type { LucideIcon } from 'lucide-vue-next';
import type { Config } from 'ziggy-js';
import type { ColumnDef as TanstackColumnDef } from '@tanstack/vue-table'
import Announcement from '@/pages/global/announcement/Announcement.vue';

export interface Auth {
    staff: Staff;
    access_token: string;
    refresh_token: string;
}

export interface BreadcrumbItem {
    title: string;
    href?: string;
    onClick?: () => void
}

export interface NavItem {
    title: string;
    href: string;
    icon?: LucideIcon;
    isActive?: boolean;
    role?: string[];
}

export type AppPageProps<T extends Record<string, unknown> = Record<string, unknown>> = T & {
    name: string;
    quote: { message: string; author: string };
    auth: Auth;
    announcements: Announcement[];
    unreadAnnouncements: Announcement[];
    showAnnouncementOnLogin: boolean;
    ziggy: Config & { location: string };
    sidebarOpen: boolean;
    flash: {
        success: string | null
        error: string | null
    };
    impersonating: boolean;
};

export interface User {
    id: number;
    name: string;
    email: string;
    avatar?: string;
    email_verified_at: string | null;
    created_at: string;
    updated_at: string;
}

export interface Staff {
    encryptStaffID: string;
    employeeid: number;
    fullname: string;
    email: string;
    role_id?: number;
    role?: string;
    avatar?: string;
    entityid: number;
    as_approver: boolean;
    pis_entity: PISEntity;
    pis_subunit: PISSubunit;
    entity: Entity;
    subunit: Subunit;
    activeflag: boolean;
    activelabel: string;
}

export interface LeaveType {
    leaveID: number;
    leaveName: string;
    leaveDescription?: string;
}

export interface Tenures {
    tenureID: number;
    minYears: number;
    maxYears: number;
}

export interface ELeaveType {
    eLeaveTypeID: number;
    leave_type: LeaveType | null;
    noticeDay: number;
    accrualRate: number;
    isAccrual: boolean;
    isPartialday: boolean;
    isDeduct: boolean;
    isHomepage: boolean;
    isRoundOff: boolean;
    isRequest: boolean;
    isCountWeekend: boolean;
    isCountHoliday: boolean;
    isActive: boolean;
    isAddApprover: boolean;
    isBackdated:boolean;
    created_at: string;
    updated_at: string;
}

export interface SLeaveType {
    sLeaveTypeID: number;
    leave_type: LeaveType | null;
    noticeDay: number;
    accrualRate: number;
    isAccrual: boolean;
    isPartialday: boolean;
    isDeduct: boolean;
    isHomepage: boolean;
    isRoundOff: boolean;
    isRequest: boolean;
    isCountWeekend: boolean;
    isCountHoliday: boolean;
    isActive: boolean;
    staffID: number;
    created_at: string;
    updated_at: string;
}

export interface LeaveTypeNormalise {
    leaveTypeID: number;
    leave_type: LeaveType | null;
    noticeDay: number;
    noticeDay: number;
    accrualRate: number;
    isAccrual: boolean;
    isPartialday: boolean;
    isDeduct: boolean;
    isHomepage: boolean;
    isRoundOff: boolean;
    isRequest: boolean;
    isCountWeekend: boolean;
    isCountHoliday: boolean;
    isAddApprover: boolean;
    isBackdated:boolean;
    isActive: boolean;
    staffID: number;
    created_at: string;
    updated_at: string;
}

export interface Entity {
    encryptEntityID: string;
    entityID: number;
    entityName: string;
    entityCode: string;
    dbName: string;
    entityTimezone: string;
    entityActive: boolean;
    country: Country;
    state: State;
    encryptedID: string;
    subunit: Subunit[];
}

export interface Subunit {
    subunitID: number;
    subunitName: string;
    subunitCode: string;
    pisSubunitID: number;
    entityID: number;
    encryptedID: string;
    entity: Entity;
    country: Country;
    state: State;
    subunitTimezone: string;
    isCopy: boolean;
}

export interface PISEntity {
    entityid: number;
    entity_name: string;
    entity_code: string;
}

export interface PISSubunit {
    subunitid: number;
    entityid: number;
    subunit_name: string;
    subunit_code: string;
}

export interface Country {
    countryID: number;
    countryName: string;
    state: State[];
    holiday: Holiday[];
}

export interface State {
    stateID: number;
    stateName: string;
    country: Country;
    holiday: Holiday[];
}

export interface Holiday {
    holidayID: number;
    holidayName: string;
    holidayDate: string;
    country: Country;
    state?: State;
    e_holiday: EHoliday[];
}

export interface EHoliday {
    eHolidayID: number;
    eHolidayName: string;
    eHolidayDate: string;
    isActive: boolean;
    holiday?: Holiday;
    
}

export interface Workday {
    workdayID: number;
    dayOfWeek: number;
    workHours: number;
    weekNumber: number;
    isWorkday: boolean;
}

export interface EWorkday {
    eWorkdayID: number;
    dayOfWeek: number;
    workHours: number;
    weekNumber: number;
    isWorkday: boolean;
}

export interface Tenure {
    tenureID: number;
    minYears: number;
    maxYears: number;
    tenure_entitled: TenureEntitled[];
}

export interface TenureEntitled {
    tenureEntitledID: number;
    entitledDays: number;
    tenure: Tenure;
    e_leave_type: ELeaveType;
}

export type BreadcrumbItemType = BreadcrumbItem;

export interface ColumnConfig<T> {
  key: keyof T | string;
  label: string;
  formatter?: (row: T) => any | string | number | Date | VNode;
  hide_value?: (row: T) => string | number | Date;
  width?: number;
  style?: string;
  sticky?: 'right' | 'left'
}

export interface EditableColumnDef<TData, TValue>
  extends TanstackColumnDef<TData, TValue> {
  editable?: boolean
}

export interface Approver {
    approverID: number;
    approverName: string;
    approverEmail: string;
    level: number;
}

export interface ApproverMatrix {
    aprMatrixID: number;
    staffID: number;
    approverID: number;
    level: number;
}

export interface Approval {
    approvalID: number;
    approverLevel: number;
    remarks: string;
    statusID: number;
    status: Status;
    leaveApplyID: number;
    oilApplyID: number;
    cancelRequestID: number;
    application: LeaveApplication;
    approverID: number;
    approver: Approver;
    acted_at: Date;
    cancel_request: CancelRequest;
}

export interface LeaveApplication {
    encryptApplyID: string; 
    leaveApplyID: number;
    title: string;
    startDate: string;
    endDate: string;
    noDays: number;
    notes: string;
    attachment?: string[]; 
    statusID: number;
    eLeaveTypeID: number;
    staffID: number;
    currentApproverID: number;
    finalApproverID: number;
    submitted_at: Date;
    created_at: Date;
    e_leave_type: ELeaveType | null;
    approverName?: string;
    status: Status;
    currentApprover?: Approver;
    finalApprover?: Approver;
    staff: Staff;
    leaveType?: LeaveType | null;
    category: string;
    approvals: Approval[];
    leave_date: LeaveDate[];
    isTeamLeave?: boolean;
    isManagedStaffLeave?: boolean;
    isMyLeave?: boolean;
    isManagerLeave?: boolean;
    relationshipLabel?: string;
    encryptEntityID?: string;
    cancel_requests: CancelRequest[];
}

export interface LeaveDate {
    leaveDateID: number;
    leaveDate: string;
    leaveApplyID: number;
}

export interface Status {
    statusID: number;
    statusName: string;
    statusColor: string;
}

export interface Attachment {
    url: string
    type: 'image' | 'pdf'
    name?: string
}

export interface LeaveEntitlement {
    entitlementID: number,
    entitledDays: number,
    usedDays: number,
    balanceDays: number,
    carriedForward: number,
    year: number,
    staffID: number,
    eLeaveTypeID: number,
    sLeaveTypeID: number,
    tenureID: number,
    sTenureID: number,
    created_at: number,
    updated_at: number,
    e_leave_type: ELeaveType | null;
    s_leave_type: SLeaveType | null;
    staff: Staff,
    leaveType: LeaveType;
}

export interface OILApplication {
    badge: any;
    expiryDate: any;
    remainingDays: number;
    usedDays: any;
    lifecycleStatus: string;
    encryptApplyID: string;
    oilApplyID: number;	
    oilTitle: string;
    startDate: string;
    endDate: string;
    totalDays: number;
    reason:	string;
    attachment?: string[];
    statusID: number;
    staffID: number;
    approverID:	number;
    submitted_at: Date;	
    approved_at: Date;
    rejected_at: Date;
    status: Status;
    approver: Approver;
    staff: Staff;
    category: string;
    approvals: Approval[];
    cancel_requests: CancelRequest[];
    expiry_requests: Date;
    expiryDateFormatted: Date;
}

export interface Announcement {
    announcementID: number;
    title: string;
    content: string;
    distributeTo: string;
    attachment?: string[];
    released_at: Date;
    user: AnnouncementUser[];
}

export interface AnnouncementUser {
    annUserID: number;
    announcementID: number;
    staffID: number;
    announcement: Announcement;
}

export interface CancelRequest {
    encryptCancelID: string;
    cancelRequestID: number;
    reason: string;
    statusID: number;
    apply_id: number;
    apply_type: string;
    request_at: Date;
    leave_application: LeaveApplication;
    approvals: Approval[];
    status: Status;
}

export interface CancelRequestNormalise {
    encryptCancelID: string;
    cancelRequestID: number;
    reason: string;
    applyType: string;
    apply_id: number;
    apply_type: string;
    statusID: number;
    request_at: Date;
    title: string;
    noDays: number;
    category: string;
    status: Status;
    applyable: LeaveApplication | OILApplication;
    approvals: Approval[];
    staff: Staff;
}

export interface ExtraApprover {
    extraApproverID: number;
    approverID: number;
    level: number;
}

export interface EExtraApprover {
    eExtraApproverID: number;
    approverID: number;
    level: number;
}

export interface Column {
    label: string
    value: string
    type: string
    sortable: boolean
    searchable: boolean
    filter_type?: string
    options?: {
        label: string
        value: string | number
    }[]
}

export interface ReportType {
    label: string
    value: string
}