"use client";

import { useState, type ReactNode } from "react";
import { PageLayout } from "@/components/templates/PageLayout";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { Button } from "@/components/atoms";
import { CheckIcon, ExclamationTriangleIcon } from "@heroicons/react/24/outline";

// ============================================================================
// Types
// ============================================================================

export type Step = 1 | 2 | 3;

export interface CancellationMonth {
  value: string;
  label: string;
}

export interface CancellationFlowProps {
  /** Page icon */
  icon: ReactNode;
  /** Page title */
  title: string;
  /** Back link URL */
  backHref: string;
  /** Back link label */
  backLabel: string;
  /** Available cancellation months */
  availableMonths: CancellationMonth[];
  /** Customer email for confirmation */
  customerEmail: string;
  /** Loading state */
  loading?: boolean;
  /** Page-level blocking error */
  error?: string | null;
  /** Success message after submission */
  successMessage?: string | null;
  /** Non-blocking error message */
  formError?: string | null;
  /** Submitting state */
  submitting?: boolean;
  /** Service info to display in step 1 */
  serviceInfo: ReactNode;
  /** Notice/terms content for step 2 */
  termsContent: ReactNode;
  /** Summary content for step 3 (before email and comments) */
  summaryContent: ReactNode;
  /** Optional extra content for step 3 (after summary, before email) */
  step3ExtraContent?: ReactNode;
  /** Optional warning banner (e.g., minimum contract term) */
  warningBanner?: ReactNode;
  /** Confirmation message shown in the confirmation dialog */
  confirmMessage: string;
  /** Optional details to display in confirmation dialog */
  confirmationDetails?: Array<{ label: string; value: string }>;
  /** Called when user submits the cancellation */
  onSubmit: (data: {
    cancellationMonth: string;
    confirmRead: boolean;
    confirmCancel: boolean;
    comments?: string;
  }) => void | Promise<void>;
}

// ============================================================================
// Shared Components
// ============================================================================

const STEP_LABELS = ["Select Date", "Review Terms", "Confirm"] as const;

export function Notice({ title, children }: { title: string; children: ReactNode }) {
  return (
    <div className="bg-warning-soft/50 border-l-4 border-warning rounded-r-lg p-4">
      <div className="text-sm font-medium text-foreground mb-1">{title}</div>
      <div className="text-sm text-muted-foreground leading-relaxed">{children}</div>
    </div>
  );
}

export function InfoNotice({ title, children }: { title: string; children: ReactNode }) {
  return (
    <div className="p-4 bg-info-soft/50 border-l-4 border-info rounded-r-lg">
      <div className="text-sm font-medium text-foreground mb-1">{title}</div>
      <div className="text-sm text-muted-foreground">{children}</div>
    </div>
  );
}

function StepIndicator({ currentStep }: { currentStep: Step }) {
  return (
    <div className="flex items-center justify-center gap-2 mb-8">
      {STEP_LABELS.map((label, idx) => {
        const stepNum = (idx + 1) as Step;
        const isCompleted = stepNum < currentStep;
        const isCurrent = stepNum === currentStep;

        return (
          <div key={stepNum} className="flex items-center">
            <div className="flex items-center gap-2">
              <div
                className={`
                  w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium
                  ${isCompleted ? "bg-primary text-primary-foreground" : ""}
                  ${isCurrent ? "bg-primary text-primary-foreground ring-4 ring-primary/20" : ""}
                  ${!isCompleted && !isCurrent ? "bg-muted text-muted-foreground" : ""}
                `}
              >
                {isCompleted ? <CheckIcon className="w-4 h-4" /> : stepNum}
              </div>
              <span
                className={`text-sm hidden sm:inline ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}`}
              >
                {label}
              </span>
            </div>
            {stepNum < 3 && (
              <div
                className={`w-8 sm:w-12 h-0.5 mx-2 ${stepNum < currentStep ? "bg-primary" : "bg-border"}`}
              />
            )}
          </div>
        );
      })}
    </div>
  );
}

// ============================================================================
// Step Content Components
// ============================================================================

interface Step1ContentProps {
  serviceInfo: ReactNode;
  availableMonths: CancellationMonth[];
  selectedMonth: string;
  onMonthChange: (value: string) => void;
  canProceed: boolean;
  onContinue: () => void;
}

function Step1Content({
  serviceInfo,
  availableMonths,
  selectedMonth,
  onMonthChange,
  canProceed,
  onContinue,
}: Step1ContentProps) {
  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-foreground mb-1">Select Cancellation Date</h2>
        <p className="text-sm text-muted-foreground">
          Choose when you would like your service to end.
        </p>
      </div>
      {serviceInfo}
      <div>
        <label htmlFor="cancelMonth" className="block text-sm font-medium text-foreground mb-2">
          Cancellation Month
        </label>
        <select
          id="cancelMonth"
          value={selectedMonth}
          onChange={e => onMonthChange(e.target.value)}
          className="w-full border border-input rounded-lg px-4 py-3 text-sm bg-background text-foreground focus:ring-2 focus:ring-primary focus:border-primary"
        >
          <option value="">Select a month...</option>
          {availableMonths.map(month => (
            <option key={month.value} value={month.value}>
              {month.label}
            </option>
          ))}
        </select>
        <p className="text-xs text-muted-foreground mt-2">
          Service will end at the end of the selected month.
        </p>
      </div>
      <div className="flex justify-end pt-4">
        <Button disabled={!canProceed} onClick={onContinue}>
          Continue
        </Button>
      </div>
    </div>
  );
}

interface Step2ContentProps {
  termsContent: ReactNode;
  acceptTerms: boolean;
  onAcceptTermsChange: (checked: boolean) => void;
  confirmMonthEnd: boolean;
  onConfirmMonthEndChange: (checked: boolean) => void;
  selectedMonth: string;
  selectedMonthLabel: string | undefined;
  canProceed: boolean;
  onBack: () => void;
  onContinue: () => void;
}

function Step2Content({
  termsContent,
  acceptTerms,
  onAcceptTermsChange,
  confirmMonthEnd,
  onConfirmMonthEndChange,
  selectedMonth,
  selectedMonthLabel,
  canProceed,
  onBack,
  onContinue,
}: Step2ContentProps) {
  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-foreground mb-1">Review Cancellation Terms</h2>
        <p className="text-sm text-muted-foreground">
          Please read the following information carefully.
        </p>
      </div>
      {termsContent}
      <div className="space-y-4 p-4 bg-muted/50 rounded-lg">
        <label className="flex items-start gap-3 cursor-pointer">
          <input
            type="checkbox"
            checked={acceptTerms}
            onChange={e => onAcceptTermsChange(e.target.checked)}
            className="h-5 w-5 text-primary border-input rounded mt-0.5 focus:ring-2 focus:ring-primary"
          />
          <span className="text-sm text-foreground">
            I have read and understood the cancellation terms above.
          </span>
        </label>
        <label className="flex items-start gap-3 cursor-pointer">
          <input
            type="checkbox"
            checked={confirmMonthEnd}
            onChange={e => onConfirmMonthEndChange(e.target.checked)}
            disabled={!selectedMonth}
            className="h-5 w-5 text-primary border-input rounded mt-0.5 focus:ring-2 focus:ring-primary disabled:opacity-50"
          />
          <span className="text-sm text-foreground">
            I confirm cancellation at the end of{" "}
            <strong>{selectedMonthLabel || "the selected month"}</strong>.
          </span>
        </label>
      </div>
      <div className="flex justify-between pt-4">
        <Button variant="ghost" onClick={onBack}>
          Back
        </Button>
        <Button disabled={!canProceed} onClick={onContinue}>
          Continue
        </Button>
      </div>
    </div>
  );
}

interface Step3ContentProps {
  summaryContent: ReactNode;
  step3ExtraContent?: ReactNode;
  customerEmail: string;
  comments: string;
  onCommentsChange: (value: string) => void;
  submitting: boolean;
  canProceed: boolean;
  onBack: () => void;
  onSubmit: () => void;
}

function Step3Content({
  summaryContent,
  step3ExtraContent,
  customerEmail,
  comments,
  onCommentsChange,
  submitting,
  canProceed,
  onBack,
  onSubmit,
}: Step3ContentProps) {
  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-foreground mb-1">Confirm Your Request</h2>
        <p className="text-sm text-muted-foreground">
          Review your cancellation details and submit.
        </p>
      </div>
      {summaryContent}
      {step3ExtraContent}
      <div className="p-4 bg-muted/50 rounded-lg">
        <div className="text-sm text-muted-foreground">Confirmation will be sent to:</div>
        <div className="text-sm font-medium text-foreground">{customerEmail || "—"}</div>
      </div>
      <div>
        <label htmlFor="comments" className="block text-sm font-medium text-foreground mb-2">
          Additional Comments <span className="font-normal text-muted-foreground">(optional)</span>
        </label>
        <textarea
          id="comments"
          className="w-full border border-input rounded-lg px-4 py-3 text-sm bg-background text-foreground focus:ring-2 focus:ring-primary focus:border-primary resize-none"
          rows={3}
          value={comments}
          onChange={e => onCommentsChange(e.target.value)}
          placeholder="Any questions or special requests..."
        />
      </div>
      <div className="flex justify-between pt-4 border-t border-border">
        <Button variant="ghost" onClick={onBack}>
          Back
        </Button>
        <Button
          variant="destructive"
          onClick={onSubmit}
          disabled={submitting || !canProceed}
          loading={submitting}
          loadingText="Processing…"
        >
          Request Cancellation
        </Button>
      </div>
    </div>
  );
}

interface ConfirmDialogProps {
  confirmText: string;
  confirmationDetails: Array<{ label: string; value: string }> | undefined;
  submitting: boolean;
  onConfirm: () => void;
  onCancel: () => void;
}

function ConfirmDialog({
  confirmText,
  confirmationDetails,
  submitting,
  onConfirm,
  onCancel,
}: ConfirmDialogProps) {
  return (
    <div className="fixed inset-0 z-50 overflow-y-auto">
      <div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
        <div className="fixed inset-0 bg-background/70 backdrop-blur-sm transition-opacity"></div>
        <div className="relative z-10 inline-block align-bottom bg-card rounded-lg text-left overflow-hidden shadow-[var(--cp-shadow-3)] border border-border transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
          <div className="bg-card px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
            <div className="sm:flex sm:items-start">
              <div className="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-danger-soft sm:mx-0 sm:h-10 sm:w-10">
                <ExclamationTriangleIcon className="h-6 w-6 text-danger" />
              </div>
              <div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
                <h3 className="text-lg leading-6 font-medium text-foreground">
                  Confirm Cancellation
                </h3>
                <div className="mt-2 space-y-4">
                  <p className="text-sm text-muted-foreground">{confirmText}</p>
                  {confirmationDetails && confirmationDetails.length > 0 && (
                    <div className="rounded-lg border border-border bg-muted/40 p-3 text-sm">
                      <div className="grid grid-cols-1 gap-3">
                        {confirmationDetails.map(detail => (
                          <div key={detail.label}>
                            <div className="text-xs uppercase tracking-wide text-muted-foreground">
                              {detail.label}
                            </div>
                            <div className="text-sm font-medium text-foreground break-words">
                              {detail.value}
                            </div>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
          <div className="bg-muted px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse gap-3">
            <Button
              variant="destructive"
              onClick={onConfirm}
              loading={submitting}
              loadingText="Processing…"
            >
              Request Cancellation
            </Button>
            <Button variant="outline" onClick={onCancel} disabled={submitting}>
              Back
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// Alert Banners
// ============================================================================

function CancellationAlerts({
  formError,
  successMessage,
}: {
  formError?: string | null;
  successMessage?: string | null;
}) {
  return (
    <>
      {formError && (
        <div className="mb-6">
          <AlertBanner variant="error" title="Unable to proceed" elevated>
            {formError}
          </AlertBanner>
        </div>
      )}
      {successMessage && (
        <div className="mb-6">
          <AlertBanner variant="success" title="Request submitted" elevated>
            {successMessage}
          </AlertBanner>
        </div>
      )}
    </>
  );
}

// ============================================================================
// Step Router
// ============================================================================

interface StepRouterProps {
  step: Step;
  serviceInfo: ReactNode;
  availableMonths: CancellationMonth[];
  selectedMonth: string;
  onMonthChange: (value: string) => void;
  canProceedStep2: boolean;
  setStep: (step: Step) => void;
  termsContent: ReactNode;
  acceptTerms: boolean;
  onAcceptTermsChange: (checked: boolean) => void;
  confirmMonthEnd: boolean;
  onConfirmMonthEndChange: (checked: boolean) => void;
  selectedMonthLabel: string | undefined;
  canProceedStep3: boolean;
  summaryContent: ReactNode;
  step3ExtraContent?: ReactNode;
  customerEmail: string;
  comments: string;
  onCommentsChange: (value: string) => void;
  submitting: boolean;
  onSubmit: () => void;
}

function StepRouter(props: StepRouterProps) {
  if (props.step === 1) {
    return (
      <Step1Content
        serviceInfo={props.serviceInfo}
        availableMonths={props.availableMonths}
        selectedMonth={props.selectedMonth}
        onMonthChange={props.onMonthChange}
        canProceed={props.canProceedStep2}
        onContinue={() => props.setStep(2)}
      />
    );
  }
  if (props.step === 2) {
    return (
      <Step2Content
        termsContent={props.termsContent}
        acceptTerms={props.acceptTerms}
        onAcceptTermsChange={props.onAcceptTermsChange}
        confirmMonthEnd={props.confirmMonthEnd}
        onConfirmMonthEndChange={props.onConfirmMonthEndChange}
        selectedMonth={props.selectedMonth}
        selectedMonthLabel={props.selectedMonthLabel}
        canProceed={props.canProceedStep3}
        onBack={() => props.setStep(1)}
        onContinue={() => props.setStep(3)}
      />
    );
  }
  return (
    <Step3Content
      summaryContent={props.summaryContent}
      step3ExtraContent={props.step3ExtraContent}
      customerEmail={props.customerEmail}
      comments={props.comments}
      onCommentsChange={props.onCommentsChange}
      submitting={props.submitting}
      canProceed={props.canProceedStep3}
      onBack={() => props.setStep(2)}
      onSubmit={props.onSubmit}
    />
  );
}

// ============================================================================
// Main Component
// ============================================================================

export function CancellationFlow({
  icon,
  title,
  backHref,
  backLabel,
  availableMonths,
  customerEmail,
  loading = false,
  error = null,
  successMessage = null,
  formError = null,
  submitting = false,
  serviceInfo,
  termsContent,
  summaryContent,
  step3ExtraContent,
  warningBanner,
  confirmMessage,
  confirmationDetails,
  onSubmit,
}: CancellationFlowProps) {
  const [step, setStep] = useState<Step>(1);
  const [selectedMonth, setSelectedMonth] = useState<string>("");
  const [acceptTerms, setAcceptTerms] = useState(false);
  const [confirmMonthEnd, setConfirmMonthEnd] = useState(false);
  const [comments, setComments] = useState("");
  const [showConfirmDialog, setShowConfirmDialog] = useState(false);

  const selectedMonthInfo = availableMonths.find(m => m.value === selectedMonth);
  const canProceedStep2 = !!selectedMonth;
  const canProceedStep3 = acceptTerms && confirmMonthEnd;
  const confirmText = confirmMessage.replace("{month}", selectedMonthInfo?.label || selectedMonth);

  const handleSubmit = () => setShowConfirmDialog(true);

  const handleConfirmSubmit = () => {
    setShowConfirmDialog(false);
    const trimmedComments = comments.trim();
    void onSubmit({
      cancellationMonth: selectedMonth,
      confirmRead: acceptTerms,
      confirmCancel: confirmMonthEnd,
      ...(trimmedComments ? { comments: trimmedComments } : {}),
    });
  };

  const handleMonthChange = (value: string) => {
    setSelectedMonth(value);
    setConfirmMonthEnd(false);
  };

  const headerActions = step === 3 && canProceedStep3 && (
    <Button
      variant="destructive"
      onClick={handleSubmit}
      disabled={submitting}
      loading={submitting}
      loadingText="Processing…"
    >
      Request Cancellation
    </Button>
  );

  return (
    <PageLayout
      icon={icon}
      title={title}
      actions={headerActions}
      backLink={{ label: backLabel, href: backHref }}
      loading={loading}
      error={error}
    >
      <div className="max-w-2xl mx-auto">
        {warningBanner}
        <CancellationAlerts formError={formError} successMessage={successMessage} />
        <StepIndicator currentStep={step} />
        <div className="bg-card border border-border rounded-xl p-6 sm:p-8">
          <StepRouter
            step={step}
            setStep={setStep}
            serviceInfo={serviceInfo}
            availableMonths={availableMonths}
            selectedMonth={selectedMonth}
            onMonthChange={handleMonthChange}
            canProceedStep2={canProceedStep2}
            termsContent={termsContent}
            acceptTerms={acceptTerms}
            onAcceptTermsChange={setAcceptTerms}
            confirmMonthEnd={confirmMonthEnd}
            onConfirmMonthEndChange={setConfirmMonthEnd}
            selectedMonthLabel={selectedMonthInfo?.label}
            canProceedStep3={canProceedStep3}
            summaryContent={summaryContent}
            step3ExtraContent={step3ExtraContent}
            customerEmail={customerEmail}
            comments={comments}
            onCommentsChange={setComments}
            submitting={submitting}
            onSubmit={handleSubmit}
          />
        </div>
      </div>
      {showConfirmDialog && (
        <ConfirmDialog
          confirmText={confirmText}
          confirmationDetails={confirmationDetails}
          submitting={submitting}
          onConfirm={handleConfirmSubmit}
          onCancel={() => setShowConfirmDialog(false)}
        />
      )}
    </PageLayout>
  );
}

// ============================================================================
// Helper Components for Service Info
// ============================================================================

export function ServiceInfoGrid({ children }: { children: ReactNode }) {
  return <div className="grid grid-cols-3 gap-4 p-4 bg-muted/50 rounded-lg">{children}</div>;
}

export function ServiceInfoItem({
  label,
  value,
  mono = false,
}: {
  label: string;
  value: string;
  mono?: boolean;
}) {
  return (
    <div>
      <div className="text-xs text-muted-foreground uppercase tracking-wide">{label}</div>
      <div
        className={`text-sm font-medium text-foreground mt-0.5 ${mono ? "font-mono text-xs" : ""}`}
      >
        {value || "—"}
      </div>
    </div>
  );
}

// ============================================================================
// Helper Components for Summary
// ============================================================================

export function CancellationSummary({
  items,
  selectedMonth,
}: {
  items: Array<{ label: string; value: string }>;
  selectedMonth: string;
}) {
  return (
    <div className="p-4 bg-primary/5 border border-primary/20 rounded-lg">
      <div className="text-sm font-medium text-foreground mb-3">Cancellation Summary</div>
      <div className="grid grid-cols-2 gap-4 text-sm">
        {items.map(item => (
          <div key={item.label}>
            <span className="text-muted-foreground">{item.label}:</span>
            <div className="font-medium text-foreground">{item.value}</div>
          </div>
        ))}
        <div>
          <span className="text-muted-foreground">Effective Date:</span>
          <div className="font-medium text-foreground">End of {selectedMonth}</div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// Warning Banner Component
// ============================================================================

export function MinimumContractWarning({ endDate }: { endDate: string }) {
  return (
    <div className="mb-6 flex items-start gap-3 p-4 bg-danger-soft border border-danger/20 rounded-lg">
      <ExclamationTriangleIcon className="w-5 h-5 text-danger flex-shrink-0 mt-0.5" />
      <div>
        <div className="text-sm font-medium text-foreground">Minimum Contract Term Warning</div>
        <div className="text-sm text-muted-foreground mt-1">
          Your subscription is within the minimum contract period (ends {endDate}). Early
          cancellation may incur additional charges.
        </div>
      </div>
    </div>
  );
}
