import type { ActionFunctionArgs, HeadersFunction, LoaderFunctionArgs } from "react-router";
import { Form, useActionData, useLoaderData } from "react-router";
import { boundary } from "@shopify/shopify-app-react-router/server";
import { authenticate } from "../shopify.server";
import db from "../db.server";
import { getSettings, fromPaise, toPaise } from "../utils";
import { configurePanIndiaShipping } from "../shipping.server";
import { getEmailConfigStatus, sendBrochureTestEmail } from "../email.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const { session } = await authenticate.admin(request);
  const settings = await getSettings(session.shop);
  const email = getEmailConfigStatus();
  const rules = await db.deliveryRule.findMany({ where: { shop: session.shop }, orderBy: { prefixLength: "desc" } });
  return { settings, rules, email };
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const { session } = await authenticate.admin(request);
  const form = await request.formData();
  const intent = String(form.get("intent") || "save");

  if (intent === "save") {
    const methodName = "Standard Delivery — Pay Delivery Charge on Handover";
    const message = String(form.get("message") || "").trim();
    const defaultCharge = String(form.get("defaultCharge") || "0").trim();
    const enabled = form.get("enabled") === "on";
    if (!message) return { ok: false, message: "Customer message is required." };
    await db.appSettings.upsert({
      where: { shop: session.shop },
      update: { methodName, message, defaultChargePaise: toPaise(defaultCharge), enabled },
      create: { shop: session.shop, methodName, message, defaultChargePaise: toPaise(defaultCharge), enabled },
    });
    return { ok: true, message: "Settings saved. Configure Shopify Shipping to publish the new checkout rate." };
  }

  if (intent === "add-rule") {
    const prefix = String(form.get("pincodePrefix") || "").replace(/\D/g, "");
    const charge = toPaise(String(form.get("charge") || "0"));
    if (!/^[0-9]{1,6}$/.test(prefix)) return { ok: false, message: "Enter a 1–6 digit PIN prefix." };
    await db.deliveryRule.deleteMany({ where: { shop: session.shop, pincodePrefix: prefix } });
    await db.deliveryRule.create({ data: { shop: session.shop, pincodePrefix: prefix, prefixLength: prefix.length, chargePaise: charge } });
    return { ok: true, message: `PIN rule ${prefix} added.` };
  }

  if (intent === "delete-rule") {
    const id = String(form.get("id") || "");
    if (id) await db.deliveryRule.deleteMany({ where: { id, shop: session.shop } });
    return { ok: true, message: "PIN rule removed." };
  }

  if (intent === "test-email") {
    try {
      await sendBrochureTestEmail();
      return { ok: true, message: "Test email sent to the configured brochure-order recipient." };
    } catch (error) {
      return { ok: false, message: error instanceof Error ? error.message : "Unable to send test email." };
    }
  }

  if (intent === "configure-shipping") {
    const result = await configurePanIndiaShipping(session.shop, session.accessToken);
    return {
      ok: result.ok,
      message: `${result.message} Profiles updated: ${result.profilesUpdated}; zones created: ${result.zonesCreated}; methods created: ${result.methodsCreated}.`,
      errors: result.errors,
    };
  }

  return { ok: false, message: "Unknown action." };
};

export default function Settings() {
  const { settings, rules, email } = useLoaderData<typeof loader>();
  const action = useActionData<typeof action>();

  return (
    <div className="sb-page">
      <s-page heading="Delivery settings">
        {action?.message ? <s-banner tone={action.ok ? "success" : "critical"}>{action.message}</s-banner> : null}
        {action?.errors?.length ? <s-banner tone="warning">{action.errors.join(" | ")}</s-banner> : null}

        <div className="sb-grid sb-grid-2" style={{marginTop: 16}}>
          <div className="sb-card">
            <h3>Checkout delivery method</h3>
            <Form method="post" className="sb-form-grid">
              <input type="hidden" name="intent" value="save" />
              <label>Checkout delivery method<input className="sb-input" value={settings.methodName} readOnly /></label>
              <label>Customer message<textarea className="sb-textarea" name="message" defaultValue={settings.message} /></label>
              <label>Default delivery charge collected on handover (₹)<input className="sb-input" name="defaultCharge" type="number" min="0" step="0.01" defaultValue={fromPaise(settings.defaultChargePaise)} /></label>
              <label><input name="enabled" type="checkbox" defaultChecked={settings.enabled} /> Enable workflow</label>
              <s-button type="submit" variant="primary">Save settings</s-button>
            </Form>
          </div>

          <div className="sb-card">
            <h3>Publish Pan-India checkout rate</h3>
            <p>Clicking this creates/updates the India shipping zone on Shopify delivery profiles with a ₹0 rate and the message above.</p>
            <Form method="post">
              <input type="hidden" name="intent" value="configure-shipping" />
              <s-button type="submit" variant="primary">Configure Shopify Shipping</s-button>
            </Form>
            <p className="sb-muted" style={{marginTop: 12}}>The app does not add the real delivery charge to Shopify checkout. The actual charge remains a separate handover collection.</p>
          </div>
        </div>

        <div className="sb-card" style={{marginTop: 16}}>
          <div className="sb-toolbar"><div><h3>PIN-code charge rules</h3><p className="sb-muted">The longest matching prefix wins. Example: 7001 overrides 700.</p></div></div>
          <Form method="post" className="sb-row" style={{marginBottom: 16}}>
            <input type="hidden" name="intent" value="add-rule" />
            <input className="sb-input" style={{maxWidth: 220}} name="pincodePrefix" placeholder="PIN prefix e.g. 700" inputMode="numeric" />
            <input className="sb-input" style={{maxWidth: 220}} name="charge" placeholder="Charge ₹ e.g. 120" type="number" min="0" step="0.01" />
            <s-button type="submit">Add rule</s-button>
          </Form>
          {rules.length === 0 ? <p className="sb-muted">No overrides yet. The default charge will be used for all India.</p> : (
            <table className="sb-table"><thead><tr><th>PIN prefix</th><th>Delivery charge</th><th></th></tr></thead><tbody>
              {rules.map((rule) => <tr key={rule.id}><td>{rule.pincodePrefix}</td><td>₹{(rule.chargePaise / 100).toFixed(2)}</td><td><Form method="post"><input type="hidden" name="intent" value="delete-rule" /><input type="hidden" name="id" value={rule.id} /><s-button type="submit" variant="tertiary">Remove</s-button></Form></td></tr>)}
            </tbody></table>
          )}
        </div>
              <div className="sb-card" style={{marginTop: 16}}>
          <h3>Brochure order email</h3>
          <p>These settings are completely separate from Shopify's Sender email. The app sends brochure order requests through its own SMTP account.</p>
          <div className="sb-grid sb-grid-2" style={{marginTop: 12}}>
            <div><div className="sb-label">Recipient</div><div className="sb-kpi" style={{fontSize: 22}}>{email.recipient}</div></div>
            <div><div className="sb-label">From address</div><div className="sb-kpi" style={{fontSize: 22}}>{email.fromEmail}</div></div>
            <div><div className="sb-label">SMTP</div><div>{email.smtpHost}:{email.smtpPort} {email.configured ? <span className="sb-badge sb-collected">CONFIGURED</span> : <span className="sb-badge sb-pending">NOT CONFIGURED</span>}</div></div>
          </div>
          <Form method="post" style={{marginTop: 14}}>
            <input type="hidden" name="intent" value="test-email" />
            <s-button type="submit" variant="primary">Send test email</s-button>
          </Form>
          <p className="sb-muted" style={{marginTop: 10}}>Set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS and BROCHURE_EMAIL_FROM_EMAIL in the app server environment. The app never changes Shopify's store Sender email.</p>
        </div>
      </s-page>
    </div>
  );
}

export const headers: HeadersFunction = (headersArgs) => boundary.headers(headersArgs);
