import React, { useState, useEffect, useMemo } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import axiosInstance from '../../../utils/axiosConfig';
import { AUDITS_URL, LOCATIONS_URL, USERS_URL } from '../../../utils/config';
import { getUserIdFromToken } from '../../../utils/authUtils';
import SuccessPopup from '../../common/SuccessPopup';
import Pagination from '../../common/Pagination';
import '../activitylog/styles/ActivityLogControls.css';
import './styles/CreateAudit.css';

const ENTRIES_PER_PAGE_OPTIONS = [10, 25, 50, 100];
const DEFAULT_ENTRIES_PER_PAGE = 10;

/** True when audit has only auditor + external co-auditor(s), no internal co-auditors. */
const isAuditorAndExternalOnly = (audit) => {
    if (!audit || !(audit.coauditors || []).length) return false;
    const coauditors = audit.coauditors || [];
    return coauditors.every(
        (c) => Number(c.co_auditor_type) === 1 || c.co_auditor_type === true
    );
};

const VIEW_LIST = 'list';
const VIEW_CARD = 'card';

const UpdateAudit = () => {
    const navigate = useNavigate();
    const { id: urlId } = useParams();
    const [audits, setAudits] = useState([]);
    const [formData, setFormData] = useState({
        auditor_id: '',
        audit_name: '',
        location: '',
        coauditors: [],
        auditees: []
    });
    const [users, setUsers] = useState([]);
    const [locations, setLocations] = useState([]);
    const [loading, setLoading] = useState(false);
    const [fetchingAudits, setFetchingAudits] = useState(true);
    const [fetchingData, setFetchingData] = useState(false);
    const [auditLoaded, setAuditLoaded] = useState(false);
    const [selectedAuditId, setSelectedAuditId] = useState(urlId || null);
    const [error, setError] = useState(null);
    const [showPopup, setShowPopup] = useState(false);
    const [coauditorInput, setCoauditorInput] = useState({
        co_auditor_name: '',
        co_auditor_type: ''
    });
    const [openingFormCount, setOpeningFormCount] = useState(0);
    const [selectedAudit, setSelectedAudit] = useState(null);
    const [viewMode, setViewMode] = useState(VIEW_CARD);
    const [currentPage, setCurrentPage] = useState(1);
    const [entriesPerPage, setEntriesPerPage] = useState(DEFAULT_ENTRIES_PER_PAGE);

    const handleEntriesPerPageChange = (e) => {
        setEntriesPerPage(Number(e.target.value));
        setCurrentPage(1);
    };

    // Fetch audits list on component mount
    useEffect(() => {
        const fetchAudits = async () => {
            try {
                setFetchingAudits(true);
                const response = await axiosInstance.get(AUDITS_URL);
                if (response.data.success) {
                    setAudits(response.data.data || []);
                } else {
                    setError('Failed to load audits.');
                }
            } catch (error) {
                console.error('Error fetching audits:', error);
                setError('Failed to load audits. Please refresh the page.');
            } finally {
                setFetchingAudits(false);
            }
        };

        fetchAudits();
    }, []);

    // Fetch users, locations, audit statuses when audit is loaded
    useEffect(() => {
        if (auditLoaded) {
            const fetchData = async () => {
                try {
                    const [usersRes, locationsRes] = await Promise.all([
                        axiosInstance.get(USERS_URL).catch((err) => {
                            if (err.response?.status === 403) return { data: { data: [] } };
                            throw err;
                        }),
                        axiosInstance.get(LOCATIONS_URL)
                    ]);

                    setUsers(usersRes.data?.data || []);
                    setLocations(locationsRes.data?.data || []);
                } catch (error) {
                    if (error.response?.status !== 403) {
                        console.error('Error fetching data:', error);
                        setError('Failed to load data. Please refresh the page.');
                    }
                }
            };

            fetchData();
        }
    }, [auditLoaded]);

    // Load audit data when audit ID is provided
    const loadAuditData = async (auditId) => {
        if (!auditId) {
            setError('Please select an audit');
            return;
        }

        try {
            setFetchingData(true);
            setError(null);
            setSelectedAuditId(auditId);
            const auditRes = await axiosInstance.get(`${AUDITS_URL}/${auditId}`);

            if (auditRes.data.success && auditRes.data.data) {
                const audit = auditRes.data.data;
                
                // Convert coauditors from database format to form format
                const coauditors = (audit.coauditors || []).map(co => ({
                    co_auditor_name: co.co_auditor_name,
                    co_auditor_type: co.co_auditor_type === true ? 1 : co.co_auditor_type === false ? 0 : (typeof co.co_auditor_type === 'number' ? co.co_auditor_type : parseInt(co.co_auditor_type) || 0)
                }));

                // Extract auditee IDs
                const auditees = (audit.auditees || []).map(auditee => auditee.user_id || auditee.auditee_id);

                setFormData({
                    auditor_id: audit.auditor_id?.toString() || '',
                    audit_name: audit.audit_name || '',
                    location: audit.location?.toString() || '',
                    coauditors: coauditors,
                    auditees: auditees
                });
                setOpeningFormCount(audit.opening_form_count || 0);
                setSelectedAudit(audit);
                setAuditLoaded(true);
                // Access: when only auditor + external co-auditors, only auditor can access (checked in render)
            } else {
                setError('Audit not found.');
                setSelectedAudit(null);
            }
        } catch (error) {
            console.error('Error fetching audit:', error);
            setSelectedAudit(null);
            if (error.response?.status === 404) {
                setError('Audit not found.');
            } else {
                setError('Failed to load audit data. Please try again.');
            }
        } finally {
            setFetchingData(false);
        }
    };

    // Auto-load if ID is in URL
    useEffect(() => {
        if (urlId) {
            loadAuditData(urlId);
        }
    }, [urlId]);

    const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData(prev => ({
            ...prev,
            [name]: value
        }));
    };

    const handleCheckboxChange = (name, id) => {
        setFormData(prev => {
            const currentIds = prev[name];
            const newIds = currentIds.includes(id)
                ? currentIds.filter(item => item !== id)
                : [...currentIds, id];

            return {
                ...prev,
                [name]: newIds
            };
        });
    };

    const handleCoauditorInputChange = (e) => {
        const { name, value } = e.target;
        setCoauditorInput(prev => ({
            ...prev,
            [name]: value
        }));
    };

    const addCoauditor = () => {
        if (coauditorInput.co_auditor_name.trim() === '') {
            setError('Co-auditor name is required.');
            return;
        }

        if (!coauditorInput.co_auditor_type || coauditorInput.co_auditor_type === '') {
            setError('Co-auditor type (integer value) is required.');
            return;
        }

        const coauditorTypeInt = parseInt(coauditorInput.co_auditor_type);
        if (isNaN(coauditorTypeInt)) {
            setError('Co-auditor type must be a valid integer.');
            return;
        }

        setFormData(prev => ({
            ...prev,
            coauditors: [...prev.coauditors, {
                co_auditor_name: coauditorInput.co_auditor_name.trim(),
                co_auditor_type: coauditorTypeInt
            }]
        }));

        setCoauditorInput({
            co_auditor_name: '',
            co_auditor_type: ''
        });
    };

    const removeCoauditor = (index) => {
        setFormData(prev => ({
            ...prev,
            coauditors: prev.coauditors.filter((_, i) => i !== index)
        }));
    };

    // Go back to audit selection list when canceling from the loaded form
    const handleCancelForm = () => {
        setAuditLoaded(false);
        setSelectedAuditId(urlId || null);
        setSelectedAudit(null);
        setFormData({
            auditor_id: '',
            audit_name: '',
            location: '',
            coauditors: [],
            auditees: []
        });
        setError(null);
    };

    const handleSubmit = async (e) => {
        e.preventDefault();
        setLoading(true);
        setError(null);

        try {
            const payload = {};

            // Only include fields that have values
            if (formData.auditor_id && formData.auditor_id !== '') {
                payload.auditor_id = parseInt(formData.auditor_id);
            }

            if (formData.audit_name && formData.audit_name.trim() !== '') {
                payload.audit_name = formData.audit_name.trim();
            }

            if (formData.location && formData.location !== '') {
                payload.location = parseInt(formData.location);
            }

            // Add optional fields only if they have values
            if (formData.coauditors && formData.coauditors.length > 0) {
                payload.sat_coauditors = formData.coauditors;
            }

            if (formData.auditees && formData.auditees.length > 0) {
                payload.sat_auditees = formData.auditees;
            }

            console.log('Updating audit with payload:', payload);

            const auditId = selectedAuditId || urlId;
            const response = await axiosInstance.put(`${AUDITS_URL}/${auditId}`, payload);

            console.log('Audit update response:', response.data);

            if (response.data.success) {
                setShowPopup(true);
            } else {
                setError(response.data.message || 'Failed to update audit. Please try again.');
            }
        } catch (error) {
            console.error('Error updating audit:', error);
            console.error('Error response:', error.response);
            console.error('Error response data:', error.response?.data);
            
            let errorMessage = 'Failed to update audit. Please try again.';
            
            if (error.response) {
                errorMessage = error.response.data?.message 
                    || error.response.data?.error 
                    || `Server error: ${error.response.status} ${error.response.statusText}`;
            } else if (error.request) {
                errorMessage = 'No response from server. Please check your connection.';
            } else {
                errorMessage = error.message || 'An error occurred while updating the audit.';
            }
            
            setError(errorMessage);
        } finally {
            setLoading(false);
        }
    };

    /* Exclude closed audits from the update-audit list */
    const auditsNotClosed = useMemo(() => {
        return audits.filter((a) => {
            const name = String(a.audit_status_name || '').trim().toLowerCase();
            const id = a.audit_status_id != null ? Number(a.audit_status_id) : null;
            return name !== 'closed' && id !== 2;
        });
    }, [audits]);

    /* Pagination: hooks must run unconditionally (before any early return) */
    const sortedAudits = useMemo(() => {
        return [...auditsNotClosed].sort((a, b) => {
            const dateA = a.created_at ? new Date(a.created_at).getTime() : 0;
            const dateB = b.created_at ? new Date(b.created_at).getTime() : 0;
            return dateB - dateA;
        });
    }, [auditsNotClosed]);

    const totalEntries = sortedAudits.length;
    const totalPages = Math.max(1, Math.ceil(totalEntries / entriesPerPage));
    const paginatedAudits = useMemo(() => {
        const start = (currentPage - 1) * entriesPerPage;
        return sortedAudits.slice(start, start + entriesPerPage);
    }, [sortedAudits, currentPage, entriesPerPage]);

    useEffect(() => {
        if (currentPage > totalPages) setCurrentPage(1);
    }, [totalPages, currentPage]);

    if (fetchingData) {
        return (
            <div className="create-audit-container">
                <div style={{ textAlign: 'center', padding: '2rem' }}>
                    <p>Loading audit data...</p>
                </div>
            </div>
        );
    }

    const formatDate = (dateString) => {
        if (!dateString) return 'N/A';
        const date = new Date(dateString);
        return date.toLocaleDateString('en-US', {
            year: 'numeric',
            month: 'short',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit'
        });
    };

    const getStatusBadgeClass = (statusName) => {
        if (!statusName) return 'update-audit-badge update-audit-badge-unknown';
        const normalized = String(statusName).trim().toLowerCase();
        if (normalized === 'open') return 'update-audit-badge update-audit-badge-open';
        if (normalized === 'in progress') return 'update-audit-badge update-audit-badge-in-progress';
        if (normalized === 'closed') return 'update-audit-badge update-audit-badge-closed';
        return 'update-audit-badge update-audit-badge-unknown';
    };

    const isAuditClosed = (audit) =>
        audit && String(audit.audit_status_name || '').trim().toLowerCase() === 'closed';

    // Show audits list if audit not loaded
    if (!auditLoaded) {
        return (
            <div className="create-audit-container">
                <div className="create-audit-header">
                    <h1 className="create-audit-title">Update Audit</h1>
                    <button
                        className="btn btn-secondary"
                        onClick={() => navigate('/dashboard')}
                    >
                        Cancel
                    </button>
                </div>

                {error && (
                    <div className="error-message">
                        {error}
                    </div>
                )}

                {fetchingAudits ? (
                    <div style={{ textAlign: 'center', padding: '2rem' }}>
                        <p>Loading audits...</p>
                    </div>
                ) : (
                    <div className="update-audit-list-wrap">
                        <h2 className="update-audit-list-title">Select an Audit to Update</h2>
                        {sortedAudits.length === 0 ? (
                            <div className="update-audit-empty">
                                {audits.length === 0 ? 'No audits found.' : 'No open or in-progress audits. Only closed audits exist.'}
                            </div>
                        ) : (
                            <>
                                {sortedAudits.length > 0 && (
                                    <div className="activity-log-controls-bar update-audit-table-controls">
                                        <div className="activity-log-controls-left">
                                            <div className="show-entries">
                                                <label>Show</label>
                                                <select
                                                    className="entries-select"
                                                    value={entriesPerPage}
                                                    onChange={handleEntriesPerPageChange}
                                                    aria-label="Entries per page"
                                                >
                                                    {ENTRIES_PER_PAGE_OPTIONS.map((n) => (
                                                        <option key={n} value={n}>{n}</option>
                                                    ))}
                                                </select>
                                                <span>entries</span>
                                            </div>
                                        </div>
                                    </div>
                                )}
                                <div className="forms-tabs" style={{ marginBottom: '1rem' }}>
                                    <button
                                        type="button"
                                        className={`tab-button ${viewMode === VIEW_LIST ? 'active' : ''}`}
                                        onClick={() => setViewMode(VIEW_LIST)}
                                    >
                                        List view
                                    </button>
                                    <button
                                        type="button"
                                        className={`tab-button ${viewMode === VIEW_CARD ? 'active' : ''}`}
                                        onClick={() => setViewMode(VIEW_CARD)}
                                    >
                                        Card view
                                    </button>
                                </div>
                                {viewMode === VIEW_LIST ? (
                                    <div className="update-audit-table-wrap">
                                        <table className="update-audit-table">
                                            <thead>
                                                <tr>
                                                    <th>Name</th>
                                                    <th>ID</th>
                                                    <th>Status</th>
                                                    <th>Auditor</th>
                                                    <th>Location</th>
                                                    <th>Created</th>
                                                    <th className="update-audit-table-actions">Actions</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {paginatedAudits.map((audit) => (
                                                    <tr key={audit.audit_id}>
                                                        <td className="update-audit-table-name">{audit.audit_name || '—'}</td>
                                                        <td>#{audit.audit_id}</td>
                                                        <td>
                                                            <span className={getStatusBadgeClass(audit.audit_status_name)}>
                                                                {audit.audit_status_name || 'N/A'}
                                                            </span>
                                                        </td>
                                                        <td>{audit.auditor_name || '—'}</td>
                                                        <td>{audit.location_name || '—'}</td>
                                                        <td>{formatDate(audit.created_at)}</td>
                                                        <td className="update-audit-table-actions">
                                                            <button
                                                                type="button"
                                                                className="btn btn-primary btn-small"
                                                                onClick={() => loadAuditData(audit.audit_id)}
                                                            >
                                                                Add Observations
                                                            </button>
                                                        </td>
                                                    </tr>
                                                ))}
                                            </tbody>
                                        </table>
                                    </div>
                                ) : (
                                    <div className="update-audit-cards">
                                        {paginatedAudits.map(audit => (
                                            <article key={audit.audit_id} className="update-audit-card">
                                                <div className="update-audit-card-header">
                                                    <h3 className="update-audit-card-title">{audit.audit_name || '—'}</h3>
                                                    <span className="update-audit-card-id">#{audit.audit_id}</span>
                                                    <span className={getStatusBadgeClass(audit.audit_status_name)}>
                                                        {audit.audit_status_name || 'N/A'}
                                                    </span>
                                                </div>
                                                <div className="update-audit-card-meta">
                                                    <div className="update-audit-card-row">
                                                        <span className="update-audit-card-label">Auditor</span>
                                                        <span className="update-audit-card-value">{audit.auditor_name || '—'}</span>
                                                    </div>
                                                    <div className="update-audit-card-row">
                                                        <span className="update-audit-card-label">Location</span>
                                                        <span className="update-audit-card-value">{audit.location_name || '—'}</span>
                                                    </div>
                                                    <div className="update-audit-card-row">
                                                        <span className="update-audit-card-label">Created</span>
                                                        <span className="update-audit-card-value">{formatDate(audit.created_at)}</span>
                                                    </div>
                                                </div>
                                                <div className="update-audit-card-actions">
                                                    <button
                                                        type="button"
                                                        className="btn btn-primary"
                                                        onClick={() => loadAuditData(audit.audit_id)}
                                                    >
                                                        Add Observations
                                                    </button>
                                                </div>
                                            </article>
                                        ))}
                                    </div>
                                )}

                                {audits.length > 0 && (
                                    <Pagination
                                        currentPage={currentPage}
                                        totalPages={totalPages}
                                        totalEntries={totalEntries}
                                        entriesPerPage={entriesPerPage}
                                        onPageChange={setCurrentPage}
                                    />
                                )}
                            </>
                        )}
                    </div>
                )}
            </div>
        );
    }

    return (
        <>
            <SuccessPopup
                show={showPopup}
                message="Audit updated successfully!"
                onClose={() => {
                    setShowPopup(false);
                    setTimeout(() => navigate('/my-audits'), 0);
                }}
                onOk={() => {
                    setShowPopup(false);
                    setTimeout(() => navigate('/my-audits'), 0);
                }}
            />
            <div className="create-audit-container">
                <div className="create-audit-header">
                    <div>
                        <h1 className="create-audit-title">Update Audit</h1>
                        <p className="create-audit-meta-text" style={{ margin: '0.5rem 0 0 0', fontSize: '0.875rem' }}>
                            Audit ID: {selectedAuditId || urlId}
                        </p>
                        <p className="create-audit-meta-text" style={{ margin: '0.25rem 0 0 0', fontSize: '0.875rem', fontWeight: 500 }}>
                            Opening Forms: {openingFormCount}
                        </p>
                    </div>
                    <button
                        className="btn btn-secondary"
                        onClick={handleCancelForm}
                    >
                        Cancel
                    </button>
                </div>

                {error && (
                    <div className="error-message">
                        {error}
                    </div>
                )}

                {(() => {
                    const loggedInUserId = getUserIdFromToken();
                    const auditorOnlyExternal = selectedAudit && isAuditorAndExternalOnly(selectedAudit);
                    const isAuditor = selectedAudit && Number(selectedAudit.auditor_id) === loggedInUserId;
                    const accessDenied = auditorOnlyExternal && !isAuditor;
                    if (accessDenied) {
                        return (
                            <div className="form-group update-audit-access-denied">
                                <p className="update-audit-access-denied-text">
                                    You do not have access to this audit. Only the auditor can access and add Observations when the audit has only an auditor and external co-auditor(s).
                                </p>
                                <button type="button" className="btn btn-secondary" onClick={() => navigate('/audit-status')}>
                                    Back to Audit Status
                                </button>
                            </div>
                        );
                    }
                    return null;
                })()}

                {!selectedAudit || (() => {
                    const loggedInUserId = getUserIdFromToken();
                    const auditorOnlyExternal = selectedAudit && isAuditorAndExternalOnly(selectedAudit);
                    return !(auditorOnlyExternal && Number(selectedAudit.auditor_id) !== loggedInUserId);
                })() && (
                <div className="form-group" style={{ marginTop: '1rem' }}>
                    <label className="form-label">
                        Add Observations to this audit
                    </label>
                    <div style={{ marginTop: '1rem' }}>
                        {(() => {
                            const loggedInUserId = getUserIdFromToken();
                            const isAuditor = selectedAudit && Number(selectedAudit.auditor_id) === loggedInUserId;
                            const isInternalCoauditor = selectedAudit && (selectedAudit.coauditors || []).some(
                                (c) => Number(c.co_auditor_user_id) === loggedInUserId && (Number(c.co_auditor_type) === 0 || c.co_auditor_type === false)
                            );
                            const auditorOnlyExternal = selectedAudit && isAuditorAndExternalOnly(selectedAudit);
                            const canAddObservations = auditorOnlyExternal
                                ? !!isAuditor
                                : !!(isAuditor || isInternalCoauditor);
                            if (!canAddObservations && selectedAudit) {
                                return (
                                    <p className="form-hint update-audit-form-hint">
                                        {auditorOnlyExternal
                                            ? 'Only the auditor can add Observations when the audit has only an auditor and external co-auditor(s).'
                                            : 'Only the auditor or internal co-auditors can add Observations.'}
                                    </p>
                                );
                            }
                            return !isAuditClosed(selectedAudit) ? (
                                <button
                                    type="button"
                                    className="btn btn-primary"
                                    onClick={() => {
                                        const auditId = selectedAuditId || urlId;
                                        navigate(`/select-form-update?audit_id=${auditId}&opening_form_count=${openingFormCount}&from=update-audit`);
                                    }}
                                >
                                    Add Observations to this audit
                                </button>
                            ) : null;
                        })()}
                    </div>
                </div>
                )}
        </div>
        </>
    );
};

export default UpdateAudit;
