import React, { useEffect, useRef, useState } from 'react';
import { Button, Form, Select } from 'antd';
import { fetchUserDropdown } from '@/app/enquiries/slice';
import { useDispatch } from 'react-redux';
import type { AppDispatch } from '@/store/store';

interface User {
  id: number;
  first_name: string;
  last_name: string;
  role: string;
  role_label: string;
  role_new_label: string;
  status: string;
  transfer_status: boolean;
  is_blocked?: boolean;
  is_self?: boolean;
  user_cities: { city_name: string; city_id: number }[];
}

interface filterI {
  search: string;
  tab_key: string;
  city_id: string;
  reporting_manager_id: string | number;
  lead_user_city_id?: number | null;
  lead_user_role_name?: string;
  lead_user_id?: number | null;
  veiw_data: string | number;
}

interface DashboardProgressiveDropdownsTestProps {
  onUpdateFilters: (filterUpdates: Partial<filterI>) => void;
  onApply?: (progressiveChanged: boolean) => void;
  hideNextLevel?: boolean;
  loading: boolean | undefined;
  resetLaunchList: () => void;
  viewData: string | number; // 👈 Add this
  showCombineView: boolean;
  initialUserId?: number | null;
  initialUserRole?: string | null;
  // Array of ancestor user IDs from top to bottom, NOT including the target user.
  // e.g. for Cluster Manager: [city_head_id, gm_id]
  initialAncestorIds?: number[];
  // Fires whenever the user manually changes the selection chain
  onSelectionChainChange?: (chain: User[]) => void;
   forceEnableApply?: boolean; // NEW

}

const DashboardProgressiveDropdownsTest: React.FC<DashboardProgressiveDropdownsTestProps> = ({
  onUpdateFilters,
  onApply,
  hideNextLevel = false,
  loading,
  resetLaunchList,
  viewData,
  showCombineView,
  initialUserId,
  initialUserRole,
  initialAncestorIds,
  onSelectionChainChange,
  forceEnableApply = false, // NEW
}) => {
  const [form] = Form.useForm();
  const dispatch: AppDispatch = useDispatch();
  const salesStaticOptions = [
    { value: 'self_view', label: 'Self View' },
    { value: 'partner_view', label: 'Partner View' },
    { value: 'combine_view', label: 'Combine View' },
  ];

  const [dropdowns, setDropdowns] = useState<User[][]>([]);
  const [selectedUsers, setSelectedUsers] = useState<(User | null)[]>([]);
  const [pendingViewType, setPendingViewType] = useState<string | number>(viewData || 'combine_view');
  const pendingViewTypeRef = useRef<string | number>(viewData || 'combine_view');

  const [pendingFilters, setPendingFilters] = useState<Partial<filterI>>({});
  const [hasPendingChanges, setHasPendingChanges] = useState(false);
  const [isFetchingDropdown, setIsFetchingDropdown] = useState(true);
  const hasAutoSelected = useRef(false);

  // Keep external consumers (e.g. a "viewing as" label on a print/export page)
  // in sync with the selection chain regardless of how it changed — a pick, a
  // clear, a view-type switch, and the auto-select-from-URL walk all update
  // `selectedUsers`, so watching it here covers every path in one place
  // instead of calling onSelectionChainChange at each mutation site.
  useEffect(() => {
    onSelectionChainChange?.(selectedUsers.filter((user): user is User => user !== null));
  }, [selectedUsers]);

  const roleDropdownsDisabled = loading || pendingViewType === 'self_view' || pendingViewType === 'partner_view';

  const accumulateFilter = (updates: Partial<filterI>) => {
    setPendingFilters(prev => ({ ...prev, ...updates }));
    setHasPendingChanges(true);
  };

  const getStyledLabel = (user: User): React.ReactNode => {
  const text = `${user.first_name} ${user.last_name} (${user.role_label})`;

    if (user.is_blocked) {
      return (
        <span title="Blocked" style={{ color: '#e53e3e' }}>
          {text}
        </span>
      );
    }

    if (user.status === 'inactive') {
      return (
        <span
          title="Inactive"
          style={{
            textDecoration: 'line-through',
            textDecorationThickness: '2px',
            color: '#999',
          }}
        >
          {text}
        </span>
      );
    }

    if (user.status === 'active' && user.transfer_status) {
      return (
        <span style={{ color: '#d69e2e' }}>
          {text}
        </span>
      );
    }

    return text;
  };

  const getSearchText = (user: User) => `${user.first_name} ${user.last_name} ${user.role_label}`;

  // Fetch the user dropdown based on the selected user.
  // Returns the fetched users and appends them directly to `dropdowns`.
  const fetchDropdown = async (
    reportingManagerRole: string | null,
    reportingManagerId: number | null = null,
    cityId: number | null = null
  ): Promise<User[]> => {
    setIsFetchingDropdown(true);
    const result = await dispatch(
      fetchUserDropdown({
        filters: { reporting_manager_id: reportingManagerId },
      })
    );
    setIsFetchingDropdown(false);
    const users: User[] = (result as any)?.payload?.data || [];
    if (users.length > 0) {
      setDropdowns(prev => removeDuplicateDropdowns([...prev, users]));
    }
    return users;
  };

  const handleSelect = (index: number, userId: number) => {
    const selectedUser = dropdowns[index].find(u => u.id === userId); // Find the selected user in the current dropdown
    if (!selectedUser) return;

    const cityId = selectedUser.user_cities?.[0]?.city_id ?? null; // Get the city ID from the selected user

    // Reset form fields for all subsequent dropdown levels to clear stale Form store values
    for (let i = index + 1; i < dropdowns.length; i++) {
      form.setFieldValue(`role-${i}`, null);
    }

    // Trim arrays up to current index, add the selected user
    const newSelectedUsers = [...selectedUsers.slice(0, index), selectedUser];
    const newDropdowns = [...dropdowns.slice(0, index + 1)]; // keep current and previous dropdowns

    setSelectedUsers(newSelectedUsers);
    setDropdowns(removeDuplicateDropdowns(newDropdowns)); // remove duplicates

    // "Team Leader (Self)" is a synthetic leaf entry (see hierarchy-chart API) — selecting
    if (selectedUser.is_self) {
      accumulateFilter({
        lead_user_city_id: cityId,
        lead_user_role_name: selectedUser.role,
        lead_user_id: userId,
        veiw_data: salesStaticOptions[0].value,
      });
    } else {
      fetchDropdown(selectedUser.role, userId, cityId);
      accumulateFilter({
        lead_user_city_id: cityId,
        lead_user_role_name: selectedUser.role,
        lead_user_id: userId,
        // Explicit 'combine_view' (not undefined) — a normal hierarchy pick must always
        // reset the view type
        veiw_data: salesStaticOptions[2].value,
      });
    }
  };

  const handleClear = (index: number) => {
    const updatedDropdowns = dropdowns.slice(0, index + 1); // keep current dropdown and previous
    const updatedSelectedUsers = [...selectedUsers.slice(0, index)]; // set selected to null for current

    // Reset form fields for the cleared level and all subsequent levels
    for (let i = index; i < dropdowns.length; i++) {
      form.setFieldValue(`role-${i}`, null);
    }

    setDropdowns(removeDuplicateDropdowns(updatedDropdowns));
    setSelectedUsers(updatedSelectedUsers);
    let filteredUpdatedSelectedUsers = updatedSelectedUsers.filter(item => item !== null);
    if (filteredUpdatedSelectedUsers.length > 0) {
      const lastSelectedUser = filteredUpdatedSelectedUsers[filteredUpdatedSelectedUsers.length - 1];
      // If there's a last selected user, update filters with their details
      if (lastSelectedUser) {
        accumulateFilter({
          lead_user_city_id: lastSelectedUser.user_cities?.[0]?.city_id ?? null,
          lead_user_role_name: lastSelectedUser.role,
          lead_user_id: lastSelectedUser.id,
          // Explicit, matching handleSelect: clearing back down to a normal user must
          // reset the view type too
          veiw_data: lastSelectedUser.is_self ? salesStaticOptions[0].value : salesStaticOptions[2].value,
        });
      } else {
        // If no last selected user, reset filters
        accumulateFilter({
          lead_user_city_id: undefined,
          lead_user_role_name: undefined,
          lead_user_id: null,
          veiw_data: salesStaticOptions[2].value,
        });
      }
    } else {
      // If no last selected user, reset filters
      accumulateFilter({
        lead_user_city_id: undefined,
        lead_user_role_name: undefined,
        lead_user_id: null,
        veiw_data: salesStaticOptions[2].value,
      });
    }
  };

  // Initial fetch on mount
  useEffect(() => {
    fetchDropdown(null, null);
  }, []);

  // Sync external viewData changes (e.g. parent resets view type via the top
  // Self/Combine/Partner toggle). Only relevant when that toggle is actually
  useEffect(() => {
    if (showCombineView && viewData !== undefined && viewData !== pendingViewTypeRef.current) {
      pendingViewTypeRef.current = viewData;
      setPendingViewType(viewData);
      dropdowns.forEach((_, i) => form.setFieldValue(`role-${i}`, null));
      setDropdowns([]);
      setSelectedUsers([]);
      fetchDropdown(null, null);
    }
  }, [viewData]);

  // Auto-select using ancestor IDs passed via URL (initialAncestorIds + initialUserId).
  // full chain = [...initialAncestorIds, initialUserId]
  // Each time a new dropdown level is appended we find the expected user for that
  // level and auto-select them, which triggers fetchDropdown → loads the next level.
  useEffect(() => {
    if (hasAutoSelected.current) return;
    if (!initialUserId) return;

    // Build the full ordered chain: ancestors first, target user last
    const fullChain = [...(initialAncestorIds ?? []), initialUserId];

    const levelIndex = dropdowns.length - 1;
    if (levelIndex < 0) return;

    // Which ID should be selected at this level?
    const expectedId = fullChain[levelIndex];
    if (!expectedId) return;

    const currentDropdown = dropdowns[levelIndex];
    const matchedUser = currentDropdown.find(u => u.id === expectedId);
    if (!matchedUser) return;

    const cityId = matchedUser.user_cities?.[0]?.city_id ?? null;
    form.setFieldValue(`role-${levelIndex}`, matchedUser.id);
    setSelectedUsers(prev => [...prev.slice(0, levelIndex), matchedUser]);

    if (levelIndex === fullChain.length - 1) {
      // Reached the target user — apply filters immediately (no Apply button needed)
      hasAutoSelected.current = true;
      onUpdateFilters({
        lead_user_city_id: cityId,
        lead_user_role_name: matchedUser.role,
        lead_user_id: matchedUser.id,
      });
      // Fetch next level so the user can drill deeper if desired
      fetchDropdown(matchedUser.role, matchedUser.id, cityId);
    } else {
      // Keep walking down the chain
      fetchDropdown(matchedUser.role, matchedUser.id, cityId);
    }
  }, [dropdowns, initialUserId]);

  const removeDuplicateDropdowns = (arrays: typeof dropdowns) => {
    return arrays.filter((arr, index, self) => {
      const ids = arr.map(user => user.id).sort().join(',');
      return index === self.findIndex(other => {
        const otherIds = other.map(user => user.id).sort().join(',');
        return ids === otherIds;
      });
    });
  };
  return (
    <div className="page-header-left-extra" style={{ display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap' }}>
      {showCombineView && (
        <Select
          value={pendingViewType as string}
          options={salesStaticOptions}
          style={{ width: '160px' }}
          disabled={!!loading}
          onChange={(val: string) => {
            pendingViewTypeRef.current = val;
            setPendingViewType(val);
            dropdowns.forEach((_, i) => form.setFieldValue(`role-${i}`, null));
            setDropdowns([]);
            setSelectedUsers([]);
            fetchDropdown(null, null);
            accumulateFilter({
              lead_user_city_id: undefined,
              lead_user_role_name: undefined,
              lead_user_id: null,
              veiw_data: val,
            });
          }}
        />
      )}
      <Form form={form} disabled={roleDropdownsDisabled} style={{ display: 'contents' }}>
        {dropdowns.map((users, index) => (
          <Form.Item key={`dropdown-${index}`} name={`role-${index}`} style={{ marginBottom: 0 }}>
            <Select
              options={users.map(user => ({
                value: user.id,
                label: getStyledLabel(user),
                searchText: getSearchText(user),
              }))}
              style={{ width: '200px' }}
              showSearch
              allowClear
              placeholder={users[0]?.role_new_label || `Role ${index + 1}`}
              filterOption={(input, option) => {
                const text = String((option as any)?.searchText ?? '');
                return text.toLowerCase().includes(input.toLowerCase());
              }}
              value={selectedUsers[index]?.id ?? undefined}
              onChange={(value: number | null | undefined) => {
                if (value === null || value === undefined) handleClear(index);
                else handleSelect(index, value);
              }}
              onClear={() => handleClear(index)}
              loading={!!loading}
              disabled={roleDropdownsDisabled}
            />
          </Form.Item>
        ))}
      </Form>
      <Button
        type="primary"
        onClick={() => {
          if (hasPendingChanges) {
            onUpdateFilters(pendingFilters);
          }
          onApply?.(hasPendingChanges);
          setPendingFilters({});
          setHasPendingChanges(false);
        }}
        disabled={loading || isFetchingDropdown ||  (!hasPendingChanges && !forceEnableApply)}
      >
        Apply
      </Button>
    </div>
  );
};

export default DashboardProgressiveDropdownsTest;