import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { useLoaderData, useActionData, Form } from "react-router";
import {
  Page,
  Layout,
  Card,
  Text,
  BlockStack,
  InlineGrid,
  InlineStack,
  Badge,
  Banner,
  Button,
  ProgressBar,
  Box,
  List,
  Divider,
} from "@shopify/polaris";
import { authenticate } from "../shopify.server";
import { registerShop } from "../services/shop.server";
import { createSubscriptionCharge } from "../services/billing.server";
import { PLAN_CONFIGS, ACTIVE_PLAN_TIERS, FEATURE_MATRIX_ROWS } from "../lib/billing-plans";
import prisma from "../db.server";
import { PlanTier } from "@prisma/client";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const { session } = await authenticate.admin(request);
  const shop = await registerShop({
    shopifyDomain: session.shop,
    accessToken: session.accessToken || "shpss_sample_token",
    scopes: (session as any).scope || "read_products,read_content",
  });

  const subscription = await prisma.subscription.findFirst({
    where: { shopId: shop.id, status: "ACTIVE" },
    orderBy: { createdAt: "desc" },
  });

  const { getPlansDictionary, getActivePlans } = await import("../services/plan-config.server");
  const plansDict = await getPlansDictionary();
  const activePlans = await getActivePlans();

  const currentPlan = (subscription?.plan || "FREE") as string;
  const currentPlanConfig = plansDict[currentPlan] || PLAN_CONFIGS[currentPlan as PlanTier] || PLAN_CONFIGS.FREE;
  const currentUsage = currentPlanConfig.aiMonthlyLimit ? (subscription?.currentUsage || 0) : 0;
  const aiMonthlyLimit = currentPlanConfig.aiMonthlyLimit;
  const usagePercentage = aiMonthlyLimit ? Math.min(100, Math.round((currentUsage / aiMonthlyLimit) * 100)) : 0;

  return {
    shop: session.shop,
    currentPlan,
    currentPlanConfig,
    currentUsage,
    aiMonthlyLimit,
    usagePercentage,
    activePlans,
    plansDict,
  };
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const { session } = await authenticate.admin(request);
  const formData = await request.formData();
  const plan = formData.get("plan") as string;

  const { getPlanByIdOrKey } = await import("../services/plan-config.server");
  const planConfig = await getPlanByIdOrKey(plan);

  if (planConfig && planConfig.isActive === false) {
    return { success: false, message: `The ${planConfig.displayName || plan} plan is currently inactive and cannot be selected.` };
  }

  if (plan && (planConfig || PLAN_CONFIGS[plan as PlanTier])) {
    const result = await createSubscriptionCharge({ shopDomain: session.shop, plan: plan as PlanTier });
    return { success: true, confirmationUrl: result.confirmationUrl, plan, message: result.message };
  }

  return { success: false, message: "Invalid plan selected." };
};

export default function BillingPage() {
  const { shop, currentPlan, currentPlanConfig, currentUsage, aiMonthlyLimit, usagePercentage, activePlans, plansDict } = useLoaderData<typeof loader>();
  const actionData = useActionData<typeof action>();

  const displayPlans = activePlans && activePlans.length > 0 ? activePlans : [];

  return (
    <Page
      title="SaaS Plans & Subscription Billing"
      subtitle="Choose the tier that fits your store size and AI shopping assistant needs."
    >
      <BlockStack gap="500">
        {actionData?.success && (
          <Banner title="Subscription Upgraded" tone="success">
            <p>Your store plan has been updated to <strong>{actionData.plan}</strong>.</p>
          </Banner>
        )}

        {/* Current Plan & Usage Progress */}
        <Layout>
          <Layout.Section>
            <Card padding="500">
              <BlockStack gap="400">
                <InlineGrid columns="1fr auto">
                  <Text as="h2" variant="headingMd">
                    💳 Current Store Plan
                  </Text>
                  <Badge tone={currentPlan === "FREE" ? "info" : "success"}>
                    {`${currentPlanConfig.displayName.toUpperCase()} (${currentPlanConfig.billingInterval === "ONE_TIME" ? "One-time" : "Monthly"})`}
                  </Badge>
                </InlineGrid>

                {aiMonthlyLimit !== null ? (
                  <BlockStack gap="200">
                    <InlineGrid columns="1fr auto">
                      <Text as="p" variant="bodyMd">
                        AI Usage: <strong>{currentUsage.toLocaleString()} / {aiMonthlyLimit.toLocaleString()}</strong> requests
                      </Text>
                      <Text as="p" variant="bodySm" tone="subdued">
                        {usagePercentage}% used
                      </Text>
                    </InlineGrid>
                    <ProgressBar progress={usagePercentage} tone={usagePercentage >= 90 ? "critical" : "primary"} />

                    {usagePercentage >= 90 && (
                      <Banner title="Approaching AI Usage Limit" tone="warning">
                        <p>You have reached {usagePercentage}% of your monthly AI requests quota. Upgrading your plan will provide higher request limits.</p>
                      </Banner>
                    )}
                  </BlockStack>
                ) : (
                  <InlineGrid columns="1fr auto">
                    <Text as="p" variant="bodyMd">
                      AI Usage: <strong>N/A</strong> (OpenAI & AI features not included in this plan)
                    </Text>
                    <Text as="p" variant="bodySm" tone="subdued">
                      Upgrade to Pro for AI features
                    </Text>
                  </InlineGrid>
                )}
              </BlockStack>
            </Card>
          </Layout.Section>

          {/* Pricing Grid Cards */}
          <Layout.Section>
            <InlineGrid columns={{ xs: 1, sm: 1, md: 3 }} gap="400">
              {displayPlans.map((config: any) => {
                const p = config.planKey || config.name;
                const isCurrent = currentPlan === p;
                const isOneTime = config.billingInterval === "ONE_TIME";

                return (
                  <Card key={p} padding="500">
                    <BlockStack gap="400">
                      <BlockStack gap="100">
                        <InlineStack align="space-between">
                          <Text as="h3" variant="headingSm">
                            {config.displayName}
                          </Text>
                          {isCurrent && <Badge tone="info">Current Plan</Badge>}
                        </InlineStack>

                        <Text as="p" variant="headingXl" fontWeight="bold">
                          ${config.price}
                          <Text as="span" variant="bodySm" tone="subdued">
                            {isOneTime ? " one-time purchase" : "/month"}
                          </Text>
                        </Text>
                      </BlockStack>

                      <Text as="p" variant="bodySm" tone="subdued">
                        {config.description}
                      </Text>

                      <Divider />

                      <Box paddingBlock="100">
                        <Text as="p" variant="bodySm" fontWeight="semibold">
                          Includes:
                        </Text>
                        <List type="bullet">
                          {(config.features || []).map((f: string, idx: number) => (
                            <List.Item key={idx}>{f}</List.Item>
                          ))}
                        </List>
                      </Box>

                      <Form method="post">
                        <input type="hidden" name="plan" value={p} />
                        <Button
                          submit
                          variant={isCurrent ? "secondary" : "primary"}
                          disabled={isCurrent}
                          fullWidth
                        >
                          {isCurrent ? "Current Plan" : isOneTime ? `Purchase ($${config.price})` : `Upgrade to ${config.displayName}`}
                        </Button>
                      </Form>
                    </BlockStack>
                  </Card>
                );
              })}
            </InlineGrid>
          </Layout.Section>

          {/* Comparison Matrix Table */}
          <Layout.Section>
            <Card padding="500">
              <BlockStack gap="400">
                <BlockStack gap="100">
                  <Text as="h2" variant="headingMd">
                    📊 Plan Feature Matrix & Entitlements
                  </Text>
                  <Text as="p" variant="bodySm" tone="subdued">
                    Single source of truth comparison across all 3 tiers. Permissions are strictly enforced on the server.
                  </Text>
                </BlockStack>

                <div style={{ overflowX: "auto" }}>
                  <table style={{ width: "100%", borderCollapse: "collapse", textAlign: "left", fontSize: "14px" }}>
                    <thead>
                      <tr style={{ borderBottom: "2px solid #E5E7EB" }}>
                        <th style={{ padding: "12px 16px", fontWeight: "600" }}>Feature</th>
                        <th style={{ padding: "12px 16px", fontWeight: "600", textAlign: "center" }}>
                          {plansDict?.FREE?.displayName || "Free"} {plansDict?.FREE?.price ? `($${plansDict.FREE.price})` : ""}
                        </th>
                        <th style={{ padding: "12px 16px", fontWeight: "600", textAlign: "center" }}>
                          {plansDict?.STARTER?.displayName || "Starter"} {plansDict?.STARTER?.price ? `($${plansDict.STARTER.price}/mo)` : ""}
                        </th>
                        <th style={{ padding: "12px 16px", fontWeight: "600", textAlign: "center" }}>
                          {plansDict?.PRO?.displayName || "Pro"} {plansDict?.PRO?.price ? `($${plansDict.PRO.price}/mo)` : ""}
                        </th>
                      </tr>
                    </thead>
                    <tbody>
                      {FEATURE_MATRIX_ROWS.map((row, idx) => (
                        <tr
                          key={idx}
                          style={{
                            borderBottom: "1px solid #F3F4F6",
                            backgroundColor: idx % 2 === 0 ? "#FFFFFF" : "#F9FAFB",
                          }}
                        >
                          <td style={{ padding: "10px 16px", fontWeight: "500" }}>{row.feature}</td>
                          <td style={{ padding: "10px 16px", textAlign: "center" }}>
                            {typeof row.free === "string" ? (
                              <strong>{row.free === "$5 one-time" || row.free === "Free" ? (plansDict?.FREE?.price === 0 ? "Free" : `$${plansDict?.FREE?.price || 0} One-Time`) : row.free}</strong>
                            ) : row.free ? (
                              <span style={{ color: "#10B981" }}>YES</span>
                            ) : (
                              <span style={{ color: "#EF4444" }}>NO</span>
                            )}
                          </td>
                          <td style={{ padding: "10px 16px", textAlign: "center" }}>
                            {typeof row.starter === "string" ? (
                              <span>{row.starter}</span>
                            ) : row.starter ? (
                              <span style={{ color: "#10B981" }}>YES</span>
                            ) : (
                              <span style={{ color: "#EF4444" }}>NO</span>
                            )}
                          </td>
                          <td style={{ padding: "10px 16px", textAlign: "center" }}>
                            {typeof row.pro === "string" ? (
                              <strong>{row.pro}</strong>
                            ) : row.pro ? (
                              <span style={{ color: "#10B981" }}>YES</span>
                            ) : (
                              <span style={{ color: "#EF4444" }}>NO</span>
                            )}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </BlockStack>
            </Card>
          </Layout.Section>
        </Layout>
      </BlockStack>
    </Page>
  );
}
