import { useState, useEffect, useRef, useMemo } from 'react';
import { createPortal } from 'react-dom';
import {
  uploadAssessment,
  fetchLocations,
  fetchCountries,
  fetchDepartments,
  fetchLocationDepartments
} from '../../api.js';
import { getSessionUserId } from '../../apiConfig.js';

const MAX_FILE_SIZE_MB = 100;
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;

function coerceAssessmentId(raw) {
  if (raw == null || raw === '') return null;
  if (typeof raw === 'bigint') return Number(raw);
  const n = Number(raw);
  return Number.isFinite(n) ? n : null;
}

/** Local calendar date as YYYY-MM-DD for `<input type="date" max>`. */
function localTodayISO() {
  const d = new Date();
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

function UploadVideoPage({ onNavigateToReview, onUploadSuccessNavigate }) {
  const [locations, setLocations] = useState([]);
  const [countries, setCountries] = useState([]);
  const [allDepartments, setAllDepartments] = useState([]);
  const [filteredDepartments, setFilteredDepartments] = useState([]);

  const [countryId, setCountryId] = useState('');
  const [locationId, setLocationId] = useState('');
  const [departmentId, setDepartmentId] = useState('');
  const [contractDetails, setContractDetails] = useState('');
  const [videoTitle, setVideoTitle] = useState('');
  const [captureDate, setCaptureDate] = useState('');
  const [captureTime, setCaptureTime] = useState('');
  const [videoFile, setVideoFile] = useState(null);
  const [remarks, setRemarks] = useState('');

  const [submitting, setSubmitting] = useState(false);
  const [result, setResult] = useState('');
  const [error, setError] = useState('');
  const [showSuccessModal, setShowSuccessModal] = useState(false);
  const [successAssessmentId, setSuccessAssessmentId] = useState(null);
  const [fileError, setFileError] = useState('');
  const fileInputRef = useRef(null);

  useEffect(() => {
    if (!showSuccessModal) return undefined;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = prev;
    };
  }, [showSuccessModal]);

  useEffect(() => {
    Promise.all([fetchLocations(), fetchCountries(), fetchDepartments()])
      .then(([locs, ctry, depts]) => {
        setLocations(Array.isArray(locs) ? locs : []);
        setCountries(Array.isArray(ctry) ? ctry : []);
        setAllDepartments(Array.isArray(depts) ? depts : []);
        setFilteredDepartments(Array.isArray(depts) ? depts : []);
      })
      .catch(() => {});
  }, []);

  const filteredLocations = useMemo(() => {
    if (!countryId) return locations;
    return locations.filter(
      (loc) => loc.country_id != null && String(loc.country_id) === String(countryId)
    );
  }, [locations, countryId]);

  useEffect(() => {
    if (!locationId) return;
    const stillValid = filteredLocations.some(
      (loc) => String(loc.location_id) === String(locationId)
    );
    if (!stillValid) {
      setLocationId('');
      setDepartmentId('');
    }
  }, [filteredLocations, locationId]);

  useEffect(() => {
    if (!locationId) {
      setFilteredDepartments(allDepartments);
      return;
    }
    fetchLocationDepartments(locationId)
      .then((mappings) => {
        if (!Array.isArray(mappings) || mappings.length === 0) {
          setFilteredDepartments(allDepartments);
          return;
        }
        const deptIds = new Set(mappings.map((m) => Number(m.department_id)));
        setFilteredDepartments(allDepartments.filter((d) => deptIds.has(Number(d.department_id))));
      })
      .catch(() => setFilteredDepartments(allDepartments));
  }, [locationId, allDepartments]);

  const getUploaderId = () => getSessionUserId();

  const validateFile = (file) => {
    if (!file) return '';
    if (file.type !== 'video/mp4') return 'Only .mp4 files are accepted.';
    if (file.size > MAX_FILE_SIZE_BYTES) return `File size must not exceed ${MAX_FILE_SIZE_MB}MB.`;
    return '';
  };

  const handleFileChange = (e) => {
    const file = e.target.files[0] || null;
    const err = validateFile(file);
    setFileError(err);
    setVideoFile(err ? null : file);
  };

  const clearForm = () => {
    setCountryId('');
    setLocationId('');
    setDepartmentId('');
    setContractDetails('');
    setVideoTitle('');
    setCaptureDate('');
    setCaptureTime('');
    setVideoFile(null);
    setRemarks('');
    setFileError('');
    setError('');
    setResult('');
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setSubmitting(true);
    setError('');
    setResult('');

    if (!videoFile) {
      setError('Please select a video file.');
      setSubmitting(false);
      return;
    }

    const today = localTodayISO();
    if (captureDate && captureDate > today) {
      setError('Video capture date cannot be in the future.');
      setSubmitting(false);
      return;
    }

    try {
      const fd = new FormData();
      fd.append('video', videoFile);
      fd.append('uploader_user_id', getUploaderId());
      fd.append('video_title', videoTitle);
      fd.append('contract_details', contractDetails);
      fd.append('video_capture_date', captureDate);
      fd.append('video_capture_time', captureDate && captureTime ? `${captureDate} ${captureTime}` : captureTime);
      fd.append('remarks', remarks);
      if (locationId) fd.append('location_id', locationId);
      if (departmentId) fd.append('department_id', departmentId);
      const loc = locations.find((l) => String(l.location_id) === String(locationId));
      const resolvedCountry =
        countryId || (loc && loc.country_id != null ? String(loc.country_id) : '');
      if (resolvedCountry) fd.append('country_id', resolvedCountry);

      const res = await uploadAssessment(fd);
      clearForm();
      setSuccessAssessmentId(coerceAssessmentId(res?.assessment_id));
      setShowSuccessModal(true);
    } catch (err) {
      setError(err.message || 'Upload failed. Please try again.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <main className="dashboard-main">
      <header className="dashboard-header">
        <div className="dashboard-header-left">
          <h1>Upload Video</h1>
          <p>Submit a new assessment video for review.</p>
        </div>
        {typeof onNavigateToReview === 'function' && (
          <div className="dashboard-header-right">
            <button
              type="button"
              className="upload-header-review-nav"
              title="Open the review queue to verify assessments"
              onClick={onNavigateToReview}
            >
              Review
            </button>
          </div>
        )}
      </header>

      <div className="upload-layout">
        <section className="upload-card">
          {result && <div className="upload-toast upload-toast--success">{result}</div>}
          {error && <div className="upload-toast upload-toast--error">{error}</div>}

          <form onSubmit={handleSubmit} className="upload-form">
            <div className="upload-field">
              <label>Country</label>
              <select
                value={countryId}
                onChange={(e) => {
                  setCountryId(e.target.value);
                  setLocationId('');
                  setDepartmentId('');
                }}
              >
                <option value="">All countries</option>
                {countries.map((c) => (
                  <option key={c.country_id} value={c.country_id}>
                    {c.country_name || `Country ${c.country_id}`}
                  </option>
                ))}
              </select>
              <span className="upload-file-hint">Narrow the list below by country (optional).</span>
            </div>

            <div className="upload-field">
              <label>Location <span className="upload-required">*</span></label>
              <select value={locationId} onChange={(e) => { setLocationId(e.target.value); setDepartmentId(''); }} required>
                <option value="">Select Sitename</option>
                {filteredLocations.map((loc) => (
                  <option key={loc.location_id} value={loc.location_id}>
                    {loc.Location_name || loc.location_name || loc.name || `Location ${loc.location_id}`}
                  </option>
                ))}
              </select>
              {countryId && filteredLocations.length === 0 ? (
                <span className="upload-file-error">No locations for this country.</span>
              ) : null}
            </div>

            <div className="upload-field">
              <label>Section / Work Area <span className="upload-required">*</span></label>
              <select value={departmentId} onChange={(e) => setDepartmentId(e.target.value)} required>
                <option value="">Select Work Area</option>
                {filteredDepartments.map((dept) => (
                  <option key={dept.department_id} value={dept.department_id}>
                    {dept.department_name || dept.name || `Dept ${dept.department_id}`}
                  </option>
                ))}
              </select>
            </div>

            <div className="upload-field">
              <label>Contract Details</label>
              <input
                type="text"
                placeholder="Enter contract details"
                value={contractDetails}
                onChange={(e) => setContractDetails(e.target.value)}
              />
            </div>

            <div className="upload-field">
              <label>Video Title <span className="upload-required">*</span></label>
              <input
                type="text"
                placeholder="Enter video title"
                value={videoTitle}
                onChange={(e) => setVideoTitle(e.target.value)}
                required
              />
            </div>

            <div className="upload-row-2">
              <div className="upload-field">
                <label>Video Capture Date <span className="upload-required">*</span></label>
                <input
                  type="date"
                  max={localTodayISO()}
                  value={captureDate}
                  onChange={(e) => setCaptureDate(e.target.value)}
                  required
                />
              </div>
              <div className="upload-field">
                <label>Video Capture Time <span className="upload-required">*</span></label>
                <input
                  type="time"
                  step="60"
                  value={captureTime}
                  onChange={(e) => setCaptureTime(e.target.value)}
                  required
                />
              </div>
            </div>

            <div className="upload-field">
              <label>Upload Video <span className="upload-required">*</span></label>
              <div className="upload-file-zone">
                <button
                  type="button"
                  className="upload-browse-btn"
                  onClick={() => fileInputRef.current?.click()}
                >
                  Browse file
                </button>
                <span className="upload-file-name">
                  {videoFile ? videoFile.name : 'No file selected'}
                </span>
                <input
                  ref={fileInputRef}
                  type="file"
                  accept="video/mp4"
                  onChange={handleFileChange}
                  hidden
                />
              </div>
              {fileError && <span className="upload-file-error">{fileError}</span>}
              <span className="upload-file-hint">Maximum size of file should not exceed {MAX_FILE_SIZE_MB}MB (.mp4)</span>
            </div>

            <div className="upload-field">
              <label>Remark <span className="upload-required">*</span></label>
              <textarea
                placeholder="Enter any additional remarks..."
                value={remarks}
                onChange={(e) => setRemarks(e.target.value)}
                rows={3}
                required
              />
            </div>

            <div className="upload-actions">
              <button type="button" className="secondary-chip-button" onClick={clearForm}>
                Clear Form
              </button>
              <button type="submit" className="primary-button" disabled={submitting || !!fileError}>
                <span>{submitting ? 'Uploading...' : 'Submit'}</span>
              </button>
            </div>
          </form>
        </section>

        <aside className="upload-guidelines">
          <h3>Guidelines</h3>
          <ol>
            <li>The files must have a maximum size of <strong>100MB</strong>.</li>
            <li>The files must have a duration of at least <strong>1 minute</strong>.</li>
            <li>The files must be of <strong>.mp4</strong> format.</li>
          </ol>
        </aside>
      </div>

      {showSuccessModal &&
        createPortal(
          <div
            className="upload-success-overlay"
            role="presentation"
            onClick={() => setShowSuccessModal(false)}
          >
            <div
              className="upload-success-modal"
              role="dialog"
              aria-modal="true"
              aria-labelledby="upload-success-title"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="upload-success-icon" aria-hidden="true">
                <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <circle cx="24" cy="24" r="22" stroke="currentColor" strokeWidth="2" />
                  <path d="M14 24l7 7 13-13" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
              <h2 id="upload-success-title" className="upload-success-title">
                Upload successful
              </h2>
              <p className="upload-success-text">
                Your video has been submitted for assessment.
                {successAssessmentId != null ? (
                  <span className="upload-success-id"> Reference ID: {successAssessmentId}</span>
                ) : null}
              </p>
              <div className="upload-success-actions">
                {typeof onUploadSuccessNavigate === 'function' ? (
                  <button
                    type="button"
                    className="primary-button"
                    onClick={() => {
                      setShowSuccessModal(false);
                      onUploadSuccessNavigate();
                    }}
                  >
                    <span>Go to My Videos</span>
                  </button>
                ) : (
                  <button type="button" className="primary-button" onClick={() => setShowSuccessModal(false)}>
                    <span>OK</span>
                  </button>
                )}
              </div>
            </div>
          </div>,
          document.body
        )}
    </main>
  );
}

export default UploadVideoPage;
