import React, { useState, memo } from 'react';
import { useAuth } from '../../../auth/AuthProvider';
import { useWizardConfig } from '../../../context/WizardConfigContext';
import { stageInitiative, launchInitiative } from '../../../services/initiativeApi';
import HelpIcon from '../../../components/HelpIcon';

const statusIcons = {
  submitted: '✓', pending_review: '⏳', error: '✗', pending: '…',
};
const statusLabels = {
  submitted: 'Submitted', pending_review: 'Queued for Review',
  error: 'Failed', pending: 'Pending',
};

const ageLabels = {
  AGE_18_24: '18–24', AGE_25_34: '25–34', AGE_35_44: '35–44',
  AGE_45_54: '45–54', AGE_55_64: '55–64', AGE_65_UP: '65+',
};
const genderLabels = { MALE: 'Male', FEMALE: 'Female', UNDETERMINED: 'All Genders' };
const scopeLabels = { local: 'Local', regional: 'Regional', national: 'National' };
const skewLabels = { young: 'Younger', mature: 'Mature' };

function SectionCard({ title, icon, children, onEdit, issues, onFix }) {
  const hasIssues = issues && issues.length > 0;
  return (
    <div className={`review-section ${hasIssues ? 'has-issues' : ''}`}>
      <div className="review-section-header">
        <div className="review-section-title">
          <span className="review-icon">{icon}</span>
          <h3>{title}</h3>
        </div>
        <div className="review-section-actions">
          {hasIssues && (
            <button className="btn btn-sm btn-fix" onClick={onFix || onEdit}>
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                <path d="M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
              </svg>
              Fix
            </button>
          )}
          {onEdit && (
            <button className="btn btn-sm btn-outline" onClick={onEdit}>Edit</button>
          )}
        </div>
      </div>
      {hasIssues && (
        <div className="review-section-issues">
          {issues.map((msg, idx) => (
            <span key={idx} className="review-issue-tag">{msg}</span>
          ))}
        </div>
      )}
      <div className="review-section-body">{children}</div>
    </div>
  );
}

function ReviewRow({ label, value, mono }) {
  return (
    <div className="review-row">
      <span className="review-label">{label}</span>
      <span className={`review-value ${mono ? 'mono' : ''}`}>{value || '—'}</span>
    </div>
  );
}

const ReviewStep = memo(function ReviewStep({ stepData, onGoToStep }) {
  const { sessionToken } = useAuth();
  const { toDisplayLabel, getChannelLabel, getChannelColor } = useWizardConfig();

  const [phase, setPhase] = useState('review');
  const [error, setError] = useState(null);
  const [initiativeId, setInitiativeId] = useState(null);
  const [billing, setBilling] = useState(null);
  const [launchResults, setLaunchResults] = useState(null);
  const [showConfirm, setShowConfirm] = useState(false);
  const [termsAccepted, setTermsAccepted] = useState(false);

  // ── Step data: 1=Objective, 2=Audience, 3=Budget, 4=Channels+Allocation, 5=Creative ──
  const objective = stepData?.[1] || {};
  const audience = stepData?.[2] || {};
  const budget = stepData?.[3] || {};
  const channelsAlloc = stepData?.[4] || {};
  const creative = stepData?.[5] || {};

  const selectedChannels = channelsAlloc.selectedChannels || [];
  const isMultiChannel = selectedChannels.length > 1;
  const totalBudget = parseFloat(budget.totalBudget) || 0;
  const allocations = channelsAlloc.allocations || {};

  const objectiveLabel = toDisplayLabel(objective.objective);
  const categoryLabel = toDisplayLabel(objective.businessCategory);

  const formatBudget = (val) => {
    const n = parseFloat(val);
    return isNaN(n) ? '—' : `$${n.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
  };

  // Validation
  const issues = [];
  if (!objective.campaignName) issues.push({ step: 1, msg: 'Campaign name is required' });
  if (!objective.objective) issues.push({ step: 1, msg: 'Objective is required' });
  if (selectedChannels.length === 0) issues.push({ step: 4, msg: 'Select at least one channel' });
  if (!totalBudget || totalBudget <= 0) issues.push({ step: 3, msg: 'Budget must be set' });
  if (isMultiChannel) {
    const totalPct = Object.values(allocations).reduce((s, v) => s + (v || 0), 0);
    if (Math.abs(totalPct - 100) > 0.01) issues.push({ step: 4, msg: 'Channel allocations must total 100%' });
  }

  // ── Stage ──
  const handleStage = async () => {
    if (issues.length > 0) return;
    setError(null);
    setPhase('staging');

    const channelPayloads = selectedChannels.map(ch => ({
      channelType: ch,
      allocationPct: isMultiChannel ? (allocations[ch] || 0) : 100,
    }));

    const payload = {
      name: objective.campaignName,
      objective: objective.objective,
      totalBudget: totalBudget,
      budgetPeriod: budget.budgetPeriod || 'monthly',
      startDate: budget.startDate,
      endDate: budget.hasEndDate ? budget.endDate : null,
      allocationStrategy: channelsAlloc.allocationStrategy || 'manual',
      businessCategory: objective.businessCategory,
      channels: channelPayloads,
      // Audience factors
      ageSkew: audience.ageSkew || null,
      marketScope: audience.marketScope || null,
      locations: audience.locations || [],
      demographics: audience.demographics || {},
      ...(initiativeId ? { initiativeId } : {}),
    };

    const stageRes = await stageInitiative(payload, sessionToken);

    if (!stageRes.ok) {
      setPhase('error');
      setError(stageRes.error || stageRes.data?.error || 'Failed to stage initiative');
      return;
    }

    const newId = stageRes.data?.initiativeId;
    if (!newId) {
      setPhase('error');
      setError('Initiative staged but no ID returned');
      return;
    }

    setInitiativeId(newId);
    setBilling(stageRes.data?.billing || null);
    setTermsAccepted(false);
    setShowConfirm(true);
    setPhase('confirm');
  };

  // ── Launch ──
  const handleConfirmLaunch = async () => {
    setShowConfirm(false);
    setError(null);
    setPhase('launching');

    const launchRes = await launchInitiative(initiativeId, sessionToken);

    if (launchRes.ok || launchRes.data?.channels) {
      setLaunchResults(launchRes.data);
      setPhase('done');
    } else {
      setLaunchResults(launchRes.data);
      setPhase('done');
      if (!launchRes.data?.channels?.length) {
        setError(launchRes.error || launchRes.data?.error || 'Launch failed — campaigns saved but not dispatched');
      }
    }
  };

  const handleCancelConfirm = () => {
    setShowConfirm(false);
    setPhase('review');
  };

  // ── Success / Results Screen ──
  if (phase === 'done') {
    const channelResults = launchResults?.channels || [];
    const successCount = channelResults.filter(c => c.status === 'submitted' || c.status === 'pending_review').length;
    const failCount = channelResults.filter(c => c.status === 'error').length;

    return (
      <div className="wizard-step-content">
        <div className="submit-success">
          <div className="success-icon">
            {failCount === 0 ? (
              <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#10B981" strokeWidth="2">
                <path d="M22 11.08V12a10 10 0 11-5.93-9.14" />
                <path d="M22 4L12 14.01l-3-3" />
              </svg>
            ) : successCount > 0 ? (
              <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#F59E0B" strokeWidth="2">
                <circle cx="12" cy="12" r="10" />
                <line x1="12" y1="8" x2="12" y2="12" />
                <line x1="12" y1="16" x2="12.01" y2="16" />
              </svg>
            ) : (
              <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#EF4444" strokeWidth="2">
                <circle cx="12" cy="12" r="10" />
                <line x1="15" y1="9" x2="9" y2="15" />
                <line x1="9" y1="9" x2="15" y2="15" />
              </svg>
            )}
          </div>

          <h2>
            {failCount === 0
              ? `Campaign ${isMultiChannel ? 'Initiative ' : ''}Launched!`
              : successCount > 0
                ? 'Partially Launched'
                : 'Launch Failed'}
          </h2>

          <p>
            {failCount === 0
              ? `Your campaign "${objective.campaignName}" has been submitted${isMultiChannel ? ` across ${selectedChannels.length} channels` : ''}.`
              : successCount > 0
                ? `${successCount} of ${channelResults.length} channels submitted successfully.`
                : 'All channel dispatches failed. Your campaign has been saved — you can retry from the Campaigns view.'}
          </p>

          {channelResults.length > 0 && (
            <div className="launch-results">
              {channelResults.map((ch, idx) => (
                <div key={idx} className={`launch-result-row ${ch.status}`}>
                  <span className="launch-ch-dot" style={{ background: getChannelColor(ch.channelType) }} />
                  <span className="launch-ch-name">{getChannelLabel(ch.channelType)}</span>
                  <span className={`launch-status ${ch.status}`}>
                    {statusIcons[ch.status] || '?'} {statusLabels[ch.status] || ch.status}
                  </span>
                  {ch.error && <span className="launch-error">{ch.error}</span>}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    );
  }

  // ── Loading states ──
  if (phase === 'staging') {
    return (
      <div className="wizard-step-content">
        <div className="phase-loading">
          <div className="loading-spinner" />
          <h3>Preparing your campaign…</h3>
          <p>Calculating fees and validating configuration</p>
        </div>
      </div>
    );
  }

  if (phase === 'launching') {
    return (
      <div className="wizard-step-content">
        <div className="phase-loading">
          <div className="loading-spinner" />
          <h3>Launching campaign…</h3>
          <p>Submitting to {isMultiChannel ? `${selectedChannels.length} ad networks` : 'ad network'}</p>
        </div>
      </div>
    );
  }

  // ── Audience summary helpers ──
  const locationSummary = audience.locations?.length > 0
    ? audience.locations.map(l => l.name).join(', ')
    : 'All regions (national)';
  const ageSummary = audience.demographics?.ageRanges?.length > 0
    ? audience.demographics.ageRanges.map(a => ageLabels[a] || a).join(', ')
    : 'All ages';
  const genderSummary = audience.demographics?.genders?.length > 0
    ? audience.demographics.genders.map(g => genderLabels[g] || g).join(', ')
    : 'All genders';

  // Group issues by step for inline display
  const issuesByStep = {};
  issues.forEach(issue => {
    if (!issuesByStep[issue.step]) issuesByStep[issue.step] = [];
    issuesByStep[issue.step].push(issue.msg);
  });

  // ── Review Layout ──
  return (
    <div className="wizard-step-content">
      <div className="step-intro">
        <div className="step-intro-header">
          <h2>Review your campaign</h2>
          <HelpIcon helpKey="client.wizard.review" label="About this step" />
        </div>
        <p>Double-check everything below before launching.</p>
      </div>

      {error && <div className="error-box">{error}</div>}

      {/* Campaign Summary - Compact Two-Column */}
      <div className="review-grid">
        {/* Left Column: Campaign + Audience */}
        <div className="review-grid-col">
          <SectionCard
            title="Campaign" icon="🎯"
            onEdit={() => onGoToStep(1)}
            issues={issuesByStep[1]}
            onFix={() => onGoToStep(1)}
          >
            <ReviewRow label="Name" value={objective.campaignName} />
            <ReviewRow label="Objective" value={objectiveLabel} />
            <ReviewRow label="Category" value={categoryLabel} />
          </SectionCard>

          <SectionCard title="Audience" icon="👥" onEdit={() => onGoToStep(2)}>
            <ReviewRow label="Locations" value={locationSummary} />
            <ReviewRow label="Age" value={ageSummary} />
            <ReviewRow label="Gender" value={genderSummary} />
            <div className="review-factors" style={{ marginTop: 8 }}>
              <span className="review-factor-chip">
                {scopeLabels[audience.marketScope] || 'National'}
              </span>
              <span className="review-factor-chip">
                {audience.ageSkew ? skewLabels[audience.ageSkew] : 'Balanced'}
              </span>
            </div>
          </SectionCard>
        </div>

        {/* Right Column: Budget + Channels + Creative */}
        <div className="review-grid-col">
          <SectionCard
            title="Budget" icon="💰"
            onEdit={() => onGoToStep(3)}
            issues={issuesByStep[3]}
            onFix={() => onGoToStep(3)}
          >
            <ReviewRow
              label={budget.budgetPeriod === 'daily' ? 'Daily' : 'Monthly'}
              value={formatBudget(totalBudget)}
            />
            <ReviewRow label="Start" value={budget.startDate} />
            {budget.hasEndDate && <ReviewRow label="End" value={budget.endDate} />}
          </SectionCard>

          <SectionCard
            title="Channels" icon="📡"
            onEdit={() => onGoToStep(4)}
            issues={issuesByStep[4]}
            onFix={() => onGoToStep(4)}
          >
            <div className="review-channels">
              {selectedChannels.length > 0 ? selectedChannels.map(ch => (
                <span key={ch} className="review-channel-chip" style={{ borderColor: getChannelColor(ch) }}>
                  <span className="review-ch-dot" style={{ background: getChannelColor(ch) }} />
                  {getChannelLabel(ch)}
                  {isMultiChannel && <span style={{ marginLeft: 'auto', fontSize: 12, color: 'var(--color-text-muted)' }}>{allocations[ch] || 0}%</span>}
                </span>
              )) : (
                <div className="review-empty-note">No channels selected</div>
              )}
            </div>
          </SectionCard>

          <SectionCard title="Creative" icon="🖼️" onEdit={() => onGoToStep(5)}>
            {(creative.headlines?.length > 0 || creative.descriptions?.length > 0) ? (
              <div className="review-creative-summary">
                <span>{creative.headlines?.length || 0} headline{(creative.headlines?.length || 0) !== 1 ? 's' : ''}</span>
                <span className="review-dot-sep">·</span>
                <span>{creative.descriptions?.length || 0} description{(creative.descriptions?.length || 0) !== 1 ? 's' : ''}</span>
                <span className="review-dot-sep">·</span>
                <span>{creative.images?.length || 0} image{(creative.images?.length || 0) !== 1 ? 's' : ''}</span>
              </div>
            ) : (
              <div className="review-empty-note">No creative assets added yet</div>
            )}
          </SectionCard>
        </div>
      </div>

      {/* Submit */}
      <div className="submit-bar">
        <div className="submit-bar-info">
          <strong>{issues.length > 0 ? 'Almost there' : 'Ready to launch?'}</strong>
          <span>
            {issues.length > 0
              ? `Fix ${issues.length} issue${issues.length > 1 ? 's' : ''} above to enable launch.`
              : isMultiChannel
                ? `Your campaign will be submitted to ${selectedChannels.map(ch => getChannelLabel(ch)).join(' and ')} for review.`
                : `Your campaign will be submitted to ${getChannelLabel(selectedChannels[0])} for review.`}
          </span>
        </div>
        <button
          className="btn btn-primary btn-lg"
          onClick={handleStage}
          disabled={issues.length > 0}
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" />
          </svg>
          {' '}Launch Campaign
        </button>
      </div>

      {/* Confirmation Modal */}
      {showConfirm && billing && (
        <ConfirmLaunchModal
          campaignName={objective.campaignName}
          objectiveLabel={objectiveLabel}
          billing={billing}
          selectedChannels={selectedChannels}
          isMultiChannel={isMultiChannel}
          termsAccepted={termsAccepted}
          onToggleTerms={() => setTermsAccepted(!termsAccepted)}
          onConfirm={handleConfirmLaunch}
          onCancel={handleCancelConfirm}
          formatBudget={formatBudget}
          getChannelLabel={getChannelLabel}
          getChannelColor={getChannelColor}
        />
      )}
    </div>
  );
});

export default ReviewStep;

// ────────────────────────────────────────────────
// Confirmation Modal
// ────────────────────────────────────────────────

function ConfirmLaunchModal({
  campaignName, objectiveLabel, billing,
  selectedChannels, isMultiChannel,
  termsAccepted, onToggleTerms, onConfirm, onCancel, formatBudget,
  getChannelLabel, getChannelColor,
}) {
  const periodLabel = billing.budgetPeriod === 'daily' ? 'day' : 'month';
  const marginPct = ((billing.marginRate || 0) * 100).toFixed(0);
  const channelBilling = billing.channels || [];

  return (
    <div className="confirm-overlay" onClick={onCancel}>
      <div className="confirm-modal" onClick={e => e.stopPropagation()}>
        <div className="confirm-header">
          <div className="confirm-icon-wrap">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#d97706" strokeWidth="2">
              <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
              <line x1="12" y1="9" x2="12" y2="13" />
              <line x1="12" y1="17" x2="12.01" y2="17" />
            </svg>
          </div>
          <h2>Confirm Campaign Launch</h2>
        </div>

        <p className="confirm-subtitle">
          You are about to launch <strong>{campaignName}</strong>. By proceeding,
          you authorize AdPlatform to charge your payment method on file for the
          advertising spend and management fees described below.
        </p>

        <div className="confirm-billing">
          <div className="confirm-billing-row">
            <span>Campaign objective</span>
            <span>{objectiveLabel}</span>
          </div>

          <div className="confirm-billing-row">
            <span>Ad spend</span>
            <span>{formatBudget(billing.adSpend)} / {periodLabel}</span>
          </div>

          {isMultiChannel && channelBilling.map((ch, idx) => (
            <div key={idx} className="confirm-billing-row confirm-billing-sub">
              <span>
                <span className="confirm-ch-dot" style={{ background: getChannelColor(ch.channelType) }} />
                {getChannelLabel(ch.channelType)} ({ch.allocationPct}%)
              </span>
              <span>{formatBudget(ch.adSpend)} / {periodLabel}</span>
            </div>
          ))}

          <div className="confirm-billing-row">
            <span>Management fee ({marginPct}%)</span>
            <span>{formatBudget(billing.managementFee)} / {periodLabel}</span>
          </div>

          {isMultiChannel && channelBilling.map((ch, idx) => (
            <div key={`fee-${idx}`} className="confirm-billing-row confirm-billing-sub">
              <span>
                <span className="confirm-ch-dot" style={{ background: getChannelColor(ch.channelType) }} />
                {getChannelLabel(ch.channelType)}
              </span>
              <span>{formatBudget(ch.managementFee)} / {periodLabel}</span>
            </div>
          ))}

          {billing.platformFee > 0 && (
            <div className="confirm-billing-row">
              <span>Platform fee</span>
              <span>{formatBudget(billing.platformFee)} / {periodLabel}</span>
            </div>
          )}

          <div className="confirm-billing-row confirm-billing-total">
            <span>Total recurring charge</span>
            <span className="confirm-amount">{formatBudget(billing.totalCharge)} / {periodLabel}</span>
          </div>
        </div>

        <div className="confirm-note">
          Ad spend will be billed to your payment method on file. Actual ad network
          charges may vary based on delivery and auction dynamics. Management fees
          are calculated at {marginPct}% of ad spend
          {billing.minManagementFee > 0 && ` (${formatBudget(billing.minManagementFee)}/mo minimum)`}.
          You can pause or cancel campaigns at any time from the Campaigns dashboard.
          {billing.pricingSource === 'client' && (
            <span className="confirm-pricing-source" title="This client has a negotiated rate">
              {' '}— Custom rate applied
            </span>
          )}
        </div>

        <label className="confirm-terms">
          <input
            type="checkbox"
            checked={termsAccepted}
            onChange={onToggleTerms}
          />
          <span>
            I authorize AdPlatform to charge up to <strong>{formatBudget(billing.totalCharge)} / {periodLabel}</strong> to
            my payment method on file. I understand that ad networks may take up
            to 48 hours to review and approve my campaigns, and that actual
            delivery and charges may vary.
          </span>
        </label>

        <div className="confirm-actions">
          <button className="btn btn-outline" onClick={onCancel}>
            Cancel
          </button>
          <button
            className="btn btn-primary btn-lg"
            onClick={onConfirm}
            disabled={!termsAccepted}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <rect x="1" y="4" width="22" height="16" rx="2" ry="2" />
              <line x1="1" y1="10" x2="23" y2="10" />
            </svg>
            {' '}Confirm &amp; Launch
          </button>
        </div>
      </div>
    </div>
  );
}
