import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { crmAPI } from '../services/crmAPI';
import type { 
  CrmLead, 
  CrmTask, 
  CrmContact, 
  CrmDeal, 
  CrmStats,
  CrmSearchParams,
  CrmApiResponse,
  CrmPaginatedResponse
} from '../types/CrmTypes';

// State interface
export interface CrmState {
  // Data
  leads: CrmLead[];
  tasks: CrmTask[];
  contacts: CrmContact[];
  deals: CrmDeal[];
  
  // Loading states
  loading: {
    leads: boolean;
    tasks: boolean;
    contacts: boolean;
    deals: boolean;
    stats: boolean;
  };
  
  // Error states
  errors: {
    leads: string | null;
    tasks: string | null;
    contacts: string | null;
    deals: string | null;
    stats: string | null;
  };
  
  // Pagination
  pagination: {
    leads: { page: number; count: number; moreRecords: boolean };
    tasks: { page: number; count: number; moreRecords: boolean };
    contacts: { page: number; count: number; moreRecords: boolean };
    deals: { page: number; count: number; moreRecords: boolean };
  };
  
  // Statistics
  stats: CrmStats | null;
  
  // Last updated timestamps
  lastUpdated: {
    leads: string | null;
    tasks: string | null;
    contacts: string | null;
    deals: string | null;
    stats: string | null;
  };
}

// Initial state
const initialState: CrmState = {
  leads: [],
  tasks: [],
  contacts: [],
  deals: [],
  loading: {
    leads: false,
    tasks: false,
    contacts: false,
    deals: false,
    stats: false,
  },
  errors: {
    leads: null,
    tasks: null,
    contacts: null,
    deals: null,
    stats: null,
  },
  pagination: {
    leads: { page: 1, count: 0, moreRecords: false },
    tasks: { page: 1, count: 0, moreRecords: false },
    contacts: { page: 1, count: 0, moreRecords: false },
    deals: { page: 1, count: 0, moreRecords: false },
  },
  stats: null,
  lastUpdated: {
    leads: null,
    tasks: null,
    contacts: null,
    deals: null,
    stats: null,
  },
};

// Async thunks
export const fetchLeads = createAsyncThunk(
  'crm/fetchLeads',
  async (params?: CrmSearchParams) => {
    const response = await crmAPI.getLeads(params);
    return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
  }
);

export const fetchTasks = createAsyncThunk(
  'crm/fetchTasks',
  async (params?: CrmSearchParams) => {
    const response = await crmAPI.getTasks(params);
    return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
  }
);

export const fetchContacts = createAsyncThunk(
  'crm/fetchContacts',
  async (params?: CrmSearchParams) => {
    const response = await crmAPI.getContacts(params);
    return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
  }
);

export const fetchDeals = createAsyncThunk(
  'crm/fetchDeals',
  async (params?: CrmSearchParams) => {
    const response = await crmAPI.getDeals(params);
    return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
  }
);

// Fetch all CRM data
export const fetchAllCrmData = createAsyncThunk(
  'crm/fetchAllData',
  async (params?: CrmSearchParams) => {
    const [leadsResponse, tasksResponse, contactsResponse, dealsResponse] = await Promise.all([
      crmAPI.getLeads(params),
      crmAPI.getTasks(params),
      crmAPI.getContacts(params),
      crmAPI.getDeals(params),
    ]);
    console.log('leads response data',leadsResponse)
    return {
      leads: leadsResponse.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
      tasks: tasksResponse.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
      contacts: contactsResponse.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
      deals: dealsResponse.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
    };
  }
);

// Slice
const crmSlice = createSlice({
  name: 'crm',
  initialState,
  reducers: {
    clearErrors: (state) => {
      state.errors = {
        leads: null,
        tasks: null,
        contacts: null,
        deals: null,
        stats: null,
      };
    },
    clearData: (state) => {
      state.leads = [];
      state.tasks = [];
      state.contacts = [];
      state.deals = [];
      state.stats = null;
    },
    setLeadsPage: (state, action: PayloadAction<number>) => {
      state.pagination.leads.page = action.payload;
    },
    setTasksPage: (state, action: PayloadAction<number>) => {
      state.pagination.tasks.page = action.payload;
    },
    setContactsPage: (state, action: PayloadAction<number>) => {
      state.pagination.contacts.page = action.payload;
    },
    setDealsPage: (state, action: PayloadAction<number>) => {
      state.pagination.deals.page = action.payload;
    },
  },
  extraReducers: (builder) => {
    // Fetch leads
    builder
      .addCase(fetchLeads.pending, (state) => {
        state.loading.leads = true;
        state.errors.leads = null;
      })
       .addCase(fetchLeads.fulfilled, (state, action) => {
         state.loading.leads = false;
         state.leads = action.payload.data || [];
         state.pagination.leads = action.payload.info || { page: 1, count: 0, moreRecords: false };
         state.lastUpdated.leads = new Date().toISOString();
       })
      .addCase(fetchLeads.rejected, (state, action) => {
        state.loading.leads = false;
        state.errors.leads = action.error.message || 'Failed to fetch leads';
      })
      
      // Fetch tasks
      .addCase(fetchTasks.pending, (state) => {
        state.loading.tasks = true;
        state.errors.tasks = null;
      })
       .addCase(fetchTasks.fulfilled, (state, action) => {
         state.loading.tasks = false;
         state.tasks = action.payload.data || [];
         state.pagination.tasks = action.payload.info || { page: 1, count: 0, moreRecords: false };
         state.lastUpdated.tasks = new Date().toISOString();
       })
      .addCase(fetchTasks.rejected, (state, action) => {
        state.loading.tasks = false;
        state.errors.tasks = action.error.message || 'Failed to fetch tasks';
      })
      
      // Fetch contacts
      .addCase(fetchContacts.pending, (state) => {
        state.loading.contacts = true;
        state.errors.contacts = null;
      })
       .addCase(fetchContacts.fulfilled, (state, action) => {
         state.loading.contacts = false;
         state.contacts = action.payload.data || [];
         state.pagination.contacts = action.payload.info || { page: 1, count: 0, moreRecords: false };
         state.lastUpdated.contacts = new Date().toISOString();
       })
      .addCase(fetchContacts.rejected, (state, action) => {
        state.loading.contacts = false;
        state.errors.contacts = action.error.message || 'Failed to fetch contacts';
      })
      
      // Fetch deals
      .addCase(fetchDeals.pending, (state) => {
        state.loading.deals = true;
        state.errors.deals = null;
      })
       .addCase(fetchDeals.fulfilled, (state, action) => {
         state.loading.deals = false;
         state.deals = action.payload.data || [];
         state.pagination.deals = action.payload.info || { page: 1, count: 0, moreRecords: false };
         state.lastUpdated.deals = new Date().toISOString();
       })
      .addCase(fetchDeals.rejected, (state, action) => {
        state.loading.deals = false;
        state.errors.deals = action.error.message || 'Failed to fetch deals';
      })
      
      // Fetch all CRM data
      .addCase(fetchAllCrmData.pending, (state) => {
        state.loading.leads = true;
        state.loading.tasks = true;
        state.loading.contacts = true;
        state.loading.deals = true;
        state.errors.leads = null;
        state.errors.tasks = null;
        state.errors.contacts = null;
        state.errors.deals = null;
      })
      .addCase(fetchAllCrmData.fulfilled, (state, action) => {
        const { leads, tasks, contacts, deals } = action.payload;
        
        state.loading.leads = false;
        state.loading.tasks = false;
        state.loading.contacts = false;
        state.loading.deals = false;
        
        state.leads = leads.data || [];
        state.tasks = tasks.data || [];
        state.contacts = contacts.data || [];
        state.deals = deals.data || [];
        
        state.pagination.leads = leads.info || { page: 1, count: 0, moreRecords: false };
        state.pagination.tasks = tasks.info || { page: 1, count: 0, moreRecords: false };
        state.pagination.contacts = contacts.info || { page: 1, count: 0, moreRecords: false };
        state.pagination.deals = deals.info || { page: 1, count: 0, moreRecords: false };
        
        const now = new Date().toISOString();
        state.lastUpdated.leads = now;
        state.lastUpdated.tasks = now;
        state.lastUpdated.contacts = now;
        state.lastUpdated.deals = now;
      })
      .addCase(fetchAllCrmData.rejected, (state, action) => {
        state.loading.leads = false;
        state.loading.tasks = false;
        state.loading.contacts = false;
        state.loading.deals = false;
        
        const errorMessage = action.error.message || 'Failed to fetch CRM data';
        state.errors.leads = errorMessage;
        state.errors.tasks = errorMessage;
        state.errors.contacts = errorMessage;
        state.errors.deals = errorMessage;
      });
  },
});

export const {
  clearErrors,
  clearData,
  setLeadsPage,
  setTasksPage,
  setContactsPage,
  setDealsPage,
} = crmSlice.actions;

export default crmSlice.reducer;
