'use client';

import React, { useCallback, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import toast from 'react-hot-toast';
import {
  FiArrowLeft, FiCalendar, FiCheck, FiClock, FiEye, FiFileText, FiRefreshCw, FiRotateCcw,
  FiSend, FiLock, FiUnlock, FiUsers, FiAlertTriangle, FiList, FiAward, FiEdit3, FiDownload, FiImage,
} from 'react-icons/fi';
import { EnterpriseLoader } from '../../../../../../../components/loader/loader';
import {
  getReport, refreshReportFromCrm, submitReport, approveReport, returnReport, reopenReport,
  lockReport, openReportPdf, downloadReportDocx,
} from '@/lib/api/audit-report-builder.api';
import type { ReportEditorModel } from '@/lib/api/types/audit-report-builder.types';
import { REPORT_STATUS_CONFIG, STAGE_CONFIG, fmtDate } from '@/lib/api/mappers/audit-report-builder.mappers';
import { RB_CSS } from './report-styles';
import HeaderPanel from './panels/HeaderPanel';
import ClausesPanel from './panels/ClausesPanel';
import SectionsPanel from './panels/SectionsPanel';
import AttendancePanel from './panels/AttendancePanel';
import ConclusionPanel from './panels/ConclusionPanel';
import NcsPanel from './panels/NcsPanel';
import PreviewPanel from './panels/PreviewPanel';
import PhotosPanel from './panels/PhotosPanel';

type TabKey = 'details' | 'clauses' | 'sections' | 'photos' | 'attendance' | 'conclusion' | 'ncs' | 'preview';

interface Props {
  rowId: number;
  reportId: number;
}

export default function ReportEditor({ rowId, reportId }: Props) {
  const router = useRouter();
  const [model, setModel] = useState<ReportEditorModel | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [tab, setTab] = useState<TabKey>('details');
  const [rev, setRev] = useState(0); // bump to remount panels from fresh server data
  const [dirty, setDirty] = useState<Record<string, boolean>>({});
  const [busy, setBusy] = useState<string | null>(null);
  const [reasonFor, setReasonFor] = useState<'return' | 'reopen' | null>(null);
  const [reason, setReason] = useState('');

  const load = useCallback(
    (silent = false) => {
      if (!silent) setLoading(true);
      return getReport(reportId)
        .then((m) => {
          setModel(m);
          setError(null);
          setDirty({});
          setRev((r) => r + 1);
        })
        .catch((e) => setError(e.message))
        .finally(() => setLoading(false));
    },
    [reportId],
  );

  useEffect(() => {
    load();
  }, [load]);

  // warn on browser close with unsaved edits
  const anyDirty = Object.values(dirty).some(Boolean);
  useEffect(() => {
    if (!anyDirty) return;
    const h = (e: BeforeUnloadEvent) => {
      e.preventDefault();
      e.returnValue = '';
    };
    window.addEventListener('beforeunload', h);
    return () => window.removeEventListener('beforeunload', h);
  }, [anyDirty]);

  const onDirty = useCallback((panel: string, d: boolean) => {
    setDirty((p) => (p[panel] === d ? p : { ...p, [panel]: d }));
  }, []);

  const back = () => {
    if (anyDirty && !window.confirm('You have unsaved changes. Leave anyway?')) return;
    router.push(`/modules/audits/${rowId}`);
  };

  const run = async (key: string, fn: () => Promise<any>, okMsg: string) => {
    setBusy(key);
    try {
      await fn();
      toast.success(okMsg);
      await load(true);
    } catch (e: any) {
      toast.error(e.message || 'Action failed', { duration: 9000, style: { whiteSpace: 'pre-line', maxWidth: 520 } });
    } finally {
      setBusy(null);
    }
  };

  const guardSaved = () => {
    if (anyDirty) {
      toast.error('Save your pending changes first (see the orange dot on the tabs).');
      return false;
    }
    return true;
  };

  if (loading)
    return (
      <div style={{ padding: 60, textAlign: 'center' }}>
        <EnterpriseLoader />
      </div>
    );

  if (error || !model)
    return (
      <div className="rb-root rb-error">
        <style>{RB_CSS}</style>
        <h3>Could not load report</h3>
        <p>{error || 'Report not found'}</p>
        <button className="rb-btn" onClick={() => router.push(`/modules/audits/${rowId}`)}>Back to audit</button>
      </div>
    );

  const { report, permissions } = model;
  const status = REPORT_STATUS_CONFIG[report.status];
  const stage = STAGE_CONFIG[report.stage_type];
  const canEdit = permissions.can_edit;
  const isFinal = report.status === 'approved' || report.status === 'locked';
  const f = model.fields;

  const tabs: { key: TabKey; label: string; icon: React.ReactNode; badge?: number; dot?: boolean }[] = [
    { key: 'details', label: 'Details', icon: <FiFileText size={14} />, dot: dirty.header },
    { key: 'clauses', label: 'Clauses', icon: <FiList size={14} />, badge: model.clauses.length, dot: dirty.clauses },
    { key: 'sections', label: 'Narrative', icon: <FiEdit3 size={14} />, dot: dirty.sections },
    { key: 'photos', label: 'Photos', icon: <FiImage size={14} /> },
    { key: 'attendance', label: 'Attendance', icon: <FiUsers size={14} />, badge: model.attendance.length, dot: dirty.attendance },
    { key: 'conclusion', label: 'Conclusion', icon: <FiAward size={14} />, dot: dirty.conclusion },
    { key: 'ncs', label: 'NCs', icon: <FiAlertTriangle size={14} />, badge: model.ncs.length },
    { key: 'preview', label: 'Preview', icon: <FiEye size={14} /> },
  ];

  const panelProps = { model, canEdit, onDirty };
  const show = (k: TabKey) => ({ display: tab === k ? 'block' : 'none' });

  return (
    <div className="rb-root">
      <style>{RB_CSS}</style>

      <button className="rb-back" onClick={back}>
        <FiArrowLeft size={14} /> Back to audit
      </button>

      {/* ── Hero ── */}
      <header className="rb-hero">
        <div className="rb-hero-rule" />
        <div className="rb-hero-inner">
          <div className="rb-hero-left">
            <div className="rb-meta-top">
              <span className="rb-code">{report.report_no ?? `Report #${report.id}`}</span>
              <span className="rb-dot" />
              <span>{stage.label} report</span>
              {report.standard_label && (<><span className="rb-dot" /><span>{report.is_combined ? 'COMBINED · ' : ''}{report.standard_label.replace(/^Combined: /, '')}</span></>)}
              <span className="rb-dot" />
              <span>Version {report.version}</span>
            </div>
            <h1 className="rb-title">{f.name || '—'}</h1>
            <div className="rb-chips">
              {f.audit_date && (
                <span className="rb-chip"><FiCalendar size={12} /> {f.audit_date}</span>
              )}
              {f.cert_no && <span className="rb-chip"><FiAward size={12} /> {f.cert_no}</span>}
              {report.submitted_at && (
                <span className="rb-chip"><FiClock size={12} /> Submitted {fmtDate(report.submitted_at)}</span>
              )}
              {report.approved_at && (
                <span className="rb-chip"><FiCheck size={12} /> Approved {fmtDate(report.approved_at)}</span>
              )}
            </div>
          </div>

          <div className="rb-hero-right">
            <span
              className="rb-status"
              style={{ ['--s-bg' as any]: status.bg, ['--s-text' as any]: status.text, ['--s-dot' as any]: status.dot }}
            >
              <span className="rb-status-dot" /> {status.label}
            </span>

            <div className="rb-actions">
              {report.has_pdf && isFinal && (
                <button className="rb-btn rb-btn-ghost-light" onClick={() => openReportPdf(report.id).catch((e) => toast.error(e.message))}>
                  <FiDownload size={13} /> Final PDF
                </button>
              )}
              <button
                className="rb-btn rb-btn-ghost-light"
                onClick={() => downloadReportDocx(report.id, report.report_no ?? `report-${report.id}`).catch((e) => toast.error(e.message))}
              >
                <FiFileText size={13} /> Word
              </button>
              {canEdit && (
                <button
                  className="rb-btn rb-btn-ghost-light"
                  disabled={busy !== null}
                  title="Re-read company / team / certificate data. Your typed text is never touched."
                  onClick={() => run('refresh', () => refreshReportFromCrm(report.id), 'Refreshed from CRM')}
                >
                  <FiRefreshCw size={13} /> Refresh CRM
                </button>
              )}
              {canEdit && (
                <button
                  className="rb-btn rb-btn-green"
                  disabled={busy !== null}
                  onClick={() => guardSaved() && run('submit', () => submitReport(report.id), 'Report submitted for approval')}
                >
                  <FiSend size={13} /> {busy === 'submit' ? 'Submitting…' : 'Submit'}
                </button>
              )}
              {permissions.can_approve && (
                <>
                  <button className="rb-btn rb-btn-amber" disabled={busy !== null} onClick={() => setReasonFor('return')}>
                    <FiRotateCcw size={13} /> Return
                  </button>
                  <button className="rb-btn rb-btn-green" disabled={busy !== null} onClick={() => run('approve', () => approveReport(report.id), 'Report approved — final PDF created')}>
                    <FiCheck size={13} /> {busy === 'approve' ? 'Approving…' : 'Approve'}
                  </button>
                </>
              )}
              {isFinal && (
                <button className="rb-btn rb-btn-ghost-light" disabled={busy !== null} onClick={() => setReasonFor('reopen')} title="Approver only">
                  <FiUnlock size={13} /> Reopen
                </button>
              )}
              {report.status === 'approved' && (
                <button className="rb-btn rb-btn-ghost-light" disabled={busy !== null} onClick={() => window.confirm('Lock this report permanently?') && run('lock', () => lockReport(report.id), 'Report locked')} title="Approver only">
                  <FiLock size={13} /> Lock
                </button>
              )}
            </div>
          </div>
        </div>
      </header>

      {/* ── Status banners ── */}
      {report.status === 'returned' && (
        <div className="rb-banner rb-banner-warn">
          <FiRotateCcw size={16} style={{ flexShrink: 0, marginTop: 2 }} />
          <span><strong>Returned for correction.</strong> {report.return_reason || 'No reason given.'}</span>
        </div>
      )}
      {report.status === 'submitted' && (
        <div className="rb-banner rb-banner-info">
          <FiClock size={16} style={{ flexShrink: 0, marginTop: 2 }} />
          <span>Waiting for approval from the scheme department. The report is read-only until it is approved or returned.</span>
        </div>
      )}
      {isFinal && (
        <div className="rb-banner rb-banner-ok">
          <FiCheck size={16} style={{ flexShrink: 0, marginTop: 2 }} />
          <span>This report is {report.status}. It prints from a frozen snapshot — later CRM changes will not alter it.</span>
        </div>
      )}

      {/* ── Tabs ── */}
      <div className="rb-tabs" role="tablist">
        {tabs.map((t) => (
          <button key={t.key} role="tab" aria-selected={tab === t.key} className={`rb-tab${tab === t.key ? ' is-active' : ''}`} onClick={() => setTab(t.key)}>
            {t.icon}
            {t.label}
            {t.badge !== undefined && t.badge > 0 && <span className="rb-tab-badge">{t.badge}</span>}
            {t.dot && <span className="rb-tab-dirty" title="Unsaved changes" />}
          </button>
        ))}
      </div>

      {/* Panels stay mounted so unsaved drafts survive tab switches */}
      <div className="rb-panel">
        <div style={show('details')}><HeaderPanel key={`h${rev}`} {...panelProps} /></div>
        <div style={show('clauses')}><ClausesPanel key={`c${rev}`} {...panelProps} onReload={() => load(true)} /></div>
        <div style={show('sections')}><SectionsPanel key={`s${rev}`} {...panelProps} /></div>
        <div style={show('photos')}><PhotosPanel key={`p${rev}`} {...panelProps} /></div>
        <div style={show('attendance')}><AttendancePanel key={`a${rev}`} {...panelProps} /></div>
        <div style={show('conclusion')}><ConclusionPanel key={`k${rev}`} {...panelProps} /></div>
        <div style={show('ncs')}><NcsPanel key={`n${rev}`} {...panelProps} /></div>
        <div style={show('preview')}><PreviewPanel report={report} active={tab === 'preview'} refreshKey={rev} clientName={f.name} /></div>
      </div>

      {/* ── Reason modal (return / reopen) ── */}
      {reasonFor && (
        <div className="rb-modal-bg" onClick={() => setReasonFor(null)}>
          <div className="rb-modal" onClick={(e) => e.stopPropagation()}>
            <h3>{reasonFor === 'return' ? 'Return to auditor' : 'Reopen report'}</h3>
            <p>
              {reasonFor === 'return'
                ? 'Tell the auditor what needs to be corrected.'
                : 'The report goes back to the auditor for correction and the version number increases. The old PDF is kept.'}
            </p>
            <textarea className="rb-textarea" rows={4} autoFocus value={reason} onChange={(e) => setReason(e.target.value)} placeholder="Reason (min 3 characters)" />
            <div className="rb-savebar" style={{ marginTop: 14 }}>
              <button className="rb-btn" onClick={() => { setReasonFor(null); setReason(''); }}>Cancel</button>
              <button
                className="rb-btn rb-btn-primary"
                disabled={reason.trim().length < 3 || busy !== null}
                onClick={async () => {
                  const kind = reasonFor;
                  const text = reason.trim();
                  setReasonFor(null);
                  setReason('');
                  await run(
                    kind,
                    () => (kind === 'return' ? returnReport(report.id, text) : reopenReport(report.id, text)),
                    kind === 'return' ? 'Report returned to auditor' : 'Report reopened',
                  );
                }}
              >
                Confirm
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
