import { useCallback, useEffect, useState } from 'react';
import { Application, ApplicationStatus } from '@/lib/mock-data';
import { onboardingService } from '@/services/onboarding.service';
import { eorService } from '@/services/eor.service';
import { auditService } from '@/services/audit.service';
import { collaborationService } from '@/services/collaboration.service';

interface UseApplicationDetailsDataParams {
  applicationId: string;
}

export function useApplicationDetailsData({ applicationId }: UseApplicationDetailsDataParams) {
  const [application, setApplication] = useState<Application | null>(null);
  const [loading, setLoading] = useState(true);
  const [documents, setDocuments] = useState<any[]>([]);
  const [eorData, setEorData] = useState<any>(null);
  const [auditLogs, setAuditLogs] = useState<any[]>([]);
  const [auditLoading, setAuditLoading] = useState(false);
  const [worknotes, setWorknotes] = useState<any[]>([]);
  const [deposits, setDeposits] = useState<any[]>([]);
  const [paymentConfigs, setPaymentConfigs] = useState<any>({});

  const refreshDocuments = useCallback(async () => {
    try {
      const docs = await onboardingService.getDocuments(applicationId);
      setDocuments(docs || []);
    } catch (error) {
      console.error('Failed to refresh documents:', error);
    }
  }, [applicationId]);

  const fetchApplication = useCallback(async (silent = false) => {
    try {
      if (!silent) setLoading(true);
      const data = await onboardingService.getApplicationById(applicationId);

      const getStageDate = (stageName: string, fallbackStatus?: string) => {
        const stage = data.progressTracking?.find((p: any) => p.stageName === stageName);
        if (stage?.stageCompletedAt) return new Date(stage.stageCompletedAt).toISOString();
        if (stage?.stageStartedAt) return new Date(stage.stageStartedAt).toISOString();
        if (fallbackStatus) {
          const history = (data.statusHistory || []).find((h: any) => h.newStatus === fallbackStatus);
          if (history) return new Date(history.createdAt).toISOString();
        }
        return undefined;
      };

      const mappedApp: Application = {
        id: data.id,
        registrationNumber: data.applicationId || 'N/A',
        name: data.applicantName,
        email: data.email,
        phone: data.phone,
        age: data.age,
        education: data.education,
        residentialAddress: data.address || data.city || '',
        businessAddress: data.address || '',
        preferredLocation: data.preferredLocation,
        state: data.state,
        ownsBike: data.ownRoyalEnfield === 'yes',
        pastExperience: data.experienceYears ? `${data.experienceYears} years` : data.description || '',
        status: data.overallStatus as ApplicationStatus,
        questionnaireMarks: data.score || data.questionnaireMarks || 0,
        questionnaireResponses: data.questionnaireResponses || [],
        rank: 0,
        totalApplicantsAtLocation: 0,
        assignedUsers: [],
        progress: data.progressPercentage || 0,
        isShortlisted: data.isShortlisted || true,
        companyName: data.companyName,
        source: data.source,
        existingDealer: data.existingDealer,
        royalEnfieldModel: data.royalEnfieldModel,
        description: data.description,
        pincode: data.pincode,
        locationType: data.locationType,
        ownRoyalEnfield: data.ownRoyalEnfield,
        address: data.address,
        submissionDate: data.createdAt ? new Date(data.createdAt).toISOString() : '',
        questionnaireDate: getStageDate('Questionnaire', 'Questionnaire Completed') || getStageDate('Questionnaire', 'Questionnaire Pending'),
        shortlistDate: getStageDate('Shortlist', 'Shortlisted'),
        level1InterviewDate: getStageDate('1st Level Interview', 'Level 1 Approved'),
        level2InterviewDate: getStageDate('2nd Level Interview', 'Level 2 Approved'),
        level3InterviewDate: getStageDate('3rd Level Interview', 'Level 3 Approved'),
        fddDate: getStageDate('FDD', 'FDD Verification'),
        loiApprovalDate: getStageDate('LOI Approval', 'LOI In Progress'),
        securityDetailsDate: getStageDate('Security Details', 'Security Details'),
        loiIssueDate: getStageDate('LOI Issue', 'LOI Issued'),
        dealerCodeDate: getStageDate('Dealer Code Generation', 'Dealer Code Generation'),
        architectureAssignedDate: getStageDate('Architecture Team Assigned', 'Architecture Team Assigned'),
        architectureDocumentDate: getStageDate('Architecture Document Upload', 'Architecture Document Upload'),
        architectureCompletionDate: getStageDate('Architecture Team Completion', 'Architecture Team Completion'),
        loaDate: getStageDate('LOA', 'LOA Pending'),
        eorCompleteDate: getStageDate('EOR Complete', 'EOR Complete'),
        inaugurationDate: getStageDate('Inauguration', 'Inauguration'),
        onboardedDate: data.overallStatus === 'Onboarded' ? (data.updatedAt ? new Date(data.updatedAt).toISOString() : new Date().toISOString()) : undefined,
        progressTracking: data.progressTracking || [],
        participants: data.participants || [],
        dealerCode: data.dealerCode,
        zoneId: data.zoneId,
        regionId: data.regionId,
        areaId: data.areaId,
        districtId: data.districtId,
        stageApprovals: data.stageApprovals || [],
        fddAssignments: data.fddAssignments || [],
        constitutionType: data.constitutionType,
        architectureStatus: data.architectureStatus,
        statutoryStatus: data.statutoryStatus,
        panNumber: data.panNumber,
        gstNumber: data.gstNumber,
        bankName: data.bankName,
        accountNumber: data.accountNumber,
        ifscCode: data.ifscCode,
        branchName: data.branchName,
        accountHolderName: data.accountHolderName,
        registeredAddress: data.registeredAddress,
      };

      setApplication(mappedApp);
      if (data.uploadedDocuments) setDocuments(data.uploadedDocuments || []);
    } catch (error) {
      console.error('Failed to fetch application details', error);
    } finally {
      setLoading(false);
    }
  }, [applicationId]);

  const fetchEorData = useCallback(async () => {
    if (!applicationId) return;
    try {
      const resp = await eorService.getChecklist(applicationId);
      if (resp.success && resp.data) setEorData(resp.data);
    } catch {
      setEorData(null);
    }
  }, [applicationId]);

  const getDeposit = (type: string) => deposits.find((d) => d.depositType === type);

  useEffect(() => {
    if (!applicationId) return;
    fetchApplication();
    refreshDocuments();
  }, [applicationId]);

  useEffect(() => {
    if (applicationId) fetchEorData();
  }, [applicationId, application?.status]);

  useEffect(() => {
    if (!application?.id) return;
    const fetchAuditAndWorknotes = async () => {
      setAuditLoading(true);
      try {
        const logs = await auditService.getAuditLogs('application', application.id, 1, 100);
        setAuditLogs(Array.isArray(logs) ? logs : []);
      } catch {
        setAuditLogs([]);
      } finally {
        setAuditLoading(false);
      }
      try {
        const res = await collaborationService.getWorknotes('application', application.id);
        setWorknotes(res.data || []);
      } catch {
        setWorknotes([]);
      }
    };
    fetchAuditAndWorknotes();
  }, [application?.id]);

  useEffect(() => {
    if (!applicationId) return;
    const fetchPaymentData = async () => {
      try {
        const [depositData, configData] = await Promise.all([
          onboardingService.getSecurityDeposit(applicationId),
          onboardingService.getSystemConfigs({ category: 'SECURITY_DEPOSIT', format: 'map' }),
        ]);
        setDeposits(Array.isArray(depositData) ? depositData : [depositData].filter(Boolean));
        setPaymentConfigs(configData || {});
      } catch (error) {
        console.error('Failed to fetch payment data', error);
      }
    };
    fetchPaymentData();
  }, [applicationId]);

  return {
    application,
    loading,
    setLoading,
    documents,
    setDocuments,
    eorData,
    auditLogs,
    auditLoading,
    worknotes,
    deposits,
    paymentConfigs,
    refreshDocuments,
    fetchApplication,
    fetchEorData,
    getDeposit,
  };
}
