import { create } from 'zustand';
import { amendmentEndpoints } from '../endpoints/amendment';
import axiosInstance from '@/utils/axios';
import {
  AmendmentDetailDTO,
  AmendmentListPageable,
  AmendmentSearchParams,
  ScheduleListPageable,
  TripListPageable,
  AmendmentListDTO,
  AmendmentApiResponse,
} from '@/shared/types/amendment';

// Convert IAvenant row data to AmendmentApiResponse for caching
const convertToApiResponse = (listDto: AmendmentListDTO): AmendmentApiResponse => ({
  id: listDto.id,
  applicationDate: listDto.createdAt,
  status: listDto.controlled ? 'controle' : 'non_controle',
  circuitCode: listDto.circuitCode,
  amendmentCode: listDto.amendmentCode,
  title: listDto.subject,
  amendmentPurpose: listDto.amendmentObject,
  type: listDto.type,
  endDate: listDto.endDate,
  establishment: listDto.establishment,
  driver: listDto.driver,
  company: listDto.company,
  clientDO: listDto.client,
  purpose: listDto.object,
  active: listDto.active,
});

interface AmendmentStore {
  amendments: AmendmentListPageable | null;
  amendment: AmendmentDetailDTO | null;
  trips: TripListPageable | null;
  schedules: ScheduleListPageable | null;
  loading: boolean;
  error: string | null;
  // Updated: Cache for row data before navigation using API response format
  cachedRowData: Map<string, AmendmentApiResponse>;

  // Actions
  getAllAmendments: (params?: AmendmentSearchParams) => Promise<void>;
  searchAmendments: (params: AmendmentSearchParams) => Promise<void>;
  getAmendmentById: (id: string) => Promise<void>;
  getAmendmentTrips: (id: string, page?: number, size?: number) => Promise<void>;
  getAmendmentSchedules: (id: string, page?: number, size?: number) => Promise<void>;
  // Updated: Cache row data using AmendmentListDTO (will be converted internally)
  cacheRowData: (id: string, rowData: AmendmentListDTO) => void;
  // Updated: Get cached data in API response format
  getCachedRowData: (id: string) => AmendmentApiResponse | null;
  // New: Clear cached data
  clearCache: () => void;
}

export const useAmendmentStore = create<AmendmentStore>((set, get) => ({
  amendments: null,
  amendment: null,
  trips: null,
  schedules: null,
  loading: false,
  error: null,
  cachedRowData: new Map(),

  getAllAmendments: async (params: AmendmentSearchParams = {}) => {
    set({ loading: true, error: null });
    try {

      const response = await axiosInstance.get<AmendmentListPageable>(
        amendmentEndpoints.amendments.getAll,
        { params }
      );

      if (!response.data) {
        throw new Error('No data received from API');
      }

      set({ amendments: response.data, loading: false });
    } catch (error: any) {
      console.error('Error fetching amendments:', {
        message: error.message,
        response: error.response?.data,
        status: error.response?.status,
        headers: error.response?.headers
      });
      set({
        error: error.response?.data?.message || error.message || 'Failed to fetch amendments',
        loading: false
      });
    }
  },

  searchAmendments: async (params: AmendmentSearchParams) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.post<AmendmentListPageable>(
        amendmentEndpoints.amendments.search,
        params
      );
      set({ amendments: response.data, loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Failed to search amendments', loading: false });
    }
  },

  getAmendmentById: async (id: string) => {
    set({ loading: true, error: null });

    // First, check if we have cached row data and use it immediately
    const cachedData = get().getCachedRowData(id);
    if (cachedData) {
      // Create a basic AmendmentDetailDTO from cached data with new structure
      const basicDetail: AmendmentDetailDTO = {
        amendment: cachedData,
        trips: [],
        schedules: [],
      };
      set({ amendment: basicDetail, loading: false });

      // Then fetch full details in the background
      try {
        const response = await axiosInstance.get<AmendmentDetailDTO>(
          amendmentEndpoints.amendments.getById(id)
        );
        set({ amendment: response.data });
      } catch (error: any) {
        console.error('Error fetching full amendment details:', error);
        // Keep the cached data if API fails
      }
    } else {
      // No cached data, fetch from API
      try {
        const response = await axiosInstance.get<AmendmentDetailDTO>(
          amendmentEndpoints.amendments.getById(id)
        );
        set({ amendment: response.data, loading: false });
      } catch (error: any) {
        set({ error: error.message || 'Failed to fetch amendment details', loading: false });
      }
    }
  },

  getAmendmentTrips: async (id: string, page: number = 0, size: number = 10) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<TripListPageable>(
        amendmentEndpoints.amendments.getTrips(id),
        { params: { page, size } }
      );
      set({ trips: response.data, loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Failed to fetch amendment trips', loading: false });
    }
  },

  getAmendmentSchedules: async (id: string, page: number = 0, size: number = 10) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get<ScheduleListPageable>(
        amendmentEndpoints.amendments.getSchedules(id),
        { params: { page, size } }
      );
      set({ schedules: response.data, loading: false });
    } catch (error: any) {
      set({ error: error.message || 'Failed to fetch amendment schedules', loading: false });
    }
  },

  cacheRowData: (id: string, rowData: AmendmentListDTO) => {
    const currentCache = get().cachedRowData;
    const newCache = new Map(currentCache);
    newCache.set(id, convertToApiResponse(rowData));
    set({ cachedRowData: newCache });
  },

  getCachedRowData: (id: string) => {
    const cache = get().cachedRowData;
    return cache.get(id) || null;
  },

  clearCache: () => {
    set({ cachedRowData: new Map() });
  },
}));
